Redis高可用之复制

前言

Web 服务器中,高可用 是指服务器可以 正常访问 的时间,衡量的标准是在 多长时间 内可以提供正常服务(99.9%99.99%99.999% 等等)。在 Redis 层面,高可用 的含义要宽泛一些,除了保证提供 正常服务(如 主从分离快速容灾技术 等),还需要考虑 数据容量扩展数据安全 等等。

Redis 中,实现 高可用 的技术主要包括 持久化复制哨兵集群,下面简单说明它们的作用,以及解决了什么样的问题:

  • 持久化:持久化是 最简单的 高可用方法。它的主要作用是 数据备份,即将数据存储在 硬盘,保证数据不会因进程退出而丢失。
  • 主从复制:复制是高可用 Redis 的基础,哨兵集群 都是在 复制基础 上实现高可用的。复制主要实现了数据的多机备份以及对于读操作的负载均衡和简单的故障恢复。缺陷是故障恢复无法自动化、写操作无法负载均衡、存储能力受到单机的限制。
  • 哨兵:在复制的基础上,哨兵实现了 自动化故障恢复。缺陷是 写操作 无法 负载均衡存储能力 受到 单机 的限制。
  • 集群:通过集群,Redis 解决了 写操作 无法 负载均衡 以及 存储能力 受到 单机限制 的问题,实现了较为 完善高可用方案

主从复制

Redis主从服务分为两类,一类是主库(master),另一类是同步主库数据的从库(slave)。主库可以进行读写操作,当写操作导致数据变化时会自动同步到从库。而从库一般是只读的(特定情况也可以写,通过参数slave-read-only指定),并接受来自主库的数据,一个主库可拥有多个从库,而一个从库只能有一个主库。

部署

环境

服务器名称 IP地址
r1 192.168.10.1
r2 192.168.10.2
r3 192.168.10.3

安装redis

1
yum install redis -y

配置

r1:/etc/redis.conf

1
2
bind 0.0.0.0
requirepass Aa123456

r2:/etc/redis.conf

1
2
3
4
bind 0.0.0.0
requirepass Aa123456
slaveof 192.168.10.1 6379
masterauth Aa123456

r3:/etc/redis.conf

1
2
3
4
bind 0.0.0.0
requirepass Aa123456
slaveof 192.168.10.1 6379
masterauth Aa123456

查看主从复制信息

r1

1
2
3
4
5
6
7
8
9
10
11
127.0.0.1:6379> INFO replication
# Replication
role:master
connected_slaves:2
slave0:ip=192.168.10.3,port=6379,state=online,offset=155,lag=1
slave1:ip=192.168.10.2,port=6379,state=online,offset=155,lag=1
master_repl_offset:155
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:154

r2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
127.0.0.1:6379> INFO replication
# Replication
role:slave
master_host:192.168.10.1
master_port:6379
master_link_status:up
master_last_io_seconds_ago:7
master_sync_in_progress:0
slave_repl_offset:309
slave_priority:100
slave_read_only:1
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

r3

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
127.0.0.1:6379> INFO replication
# Replication
role:slave
master_host:192.168.10.1
master_port:6379
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_repl_offset:365
slave_priority:100
slave_read_only:1
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

验证

进入r1 redis-cli,随便设置一个值,再进入r2和r3,查看值是否存在
r1

1
2
127.0.0.1:6379> set name r1
OK

r2

1
2
127.0.0.1:6379> get name
"r1"

r3

1
2
127.0.0.1:6379> get name
"r1"

手动切换主从

先将主库kill掉,此时r2和r3的主从状态

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
master_host:192.168.10.1
master_port:6379
master_link_status:down
master_last_io_seconds_ago:-1
master_sync_in_progress:0
slave_repl_offset:951
master_link_down_since_seconds:3
slave_priority:100
slave_read_only:1
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

登录r2,去掉从库身份,等待连接

1
2
3
4
5
6
7
8
9
10
11
127.0.0.1:6379> slaveof no one
OK
127.0.0.1:6379> INFO replication
# Replication
role:master
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

登录r3,通过命令连接新的主库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
127.0.0.1:6379> slaveof 192.168.10.2 6379
OK
127.0.0.1:6379> INFO replication
# Replication
role:slave
master_host:192.168.10.2
master_port:6379
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_repl_offset:1
slave_priority:100
slave_read_only:1
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

验证主从
r2

1
2
127.0.0.1:6379> set name r2
OK

r3

1
2
127.0.0.1:6379> get name
"r2"

最后修改三台服务器的/etc/redis.conf配置,防止重启后重载之前的主从配置。