概述
- 官方说明:https://redis.io/topics/replication
- 作用:读(Slave)写(Master)分离,容灾恢复
- 哨兵模式可以实现无人值守
- 缺点:主从复制无疑会带来延迟(Master机器同步到Slave机器),使用哨兵模式则延迟会更明显。
测试配置准备(一台主机两台备机)
拷贝多个配置文件分别命名区分 redis{port}.conf
- Master 端口6379
- Slave1 端口6380
- Slave2 端口6381
- 其他方便区别配置
- 使用后台方式启动服务
daemonize yes
pidfile
redis{port}.pidlogfile
redis{port}.logdbfilename
dump{port}.rdb
- 使用后台方式启动服务
测试1 Master<Slave1, Slave2
- 分别启动并连接上三个服务
redis-server redis{port}.conf ps -ef|grep redis|grep -v grep redis-cli -p {port}
- 客户端分别查看主从复制的信息
info replication
# Replication role:master connected_slaves:0 master_replid:d3d1de9a393d82c4dc1787800471fffba1323b3a master_replid2:0000000000000000000000000000000000000000 master_repl_offset:0 second_repl_offset:-1 repl_backlog_active:0 repl_backlog_size:1048576 repl_backlog_first_byte_offset:0 repl_backlog_histlen:0
- 开始数据主从复制
Master
set k1 v1 set k2 v2
Slave1和Slave2
get k1 slaveof 127.0.0.1 6379 get k1 get k2
- 可以看到Slave已经把Master的数据复制过来了
- Master继续设置KV,验证Slave数据同步
- 再次查看主从复制信息
info replication
可以看到匹配的信息 - Slave上进行写操作则会报错
(error) READONLY You can't write against a read only replica.
- 将Master shutdown,Slave不动
- Slave查看
info replication
- 可以看到Slave数据依然在,且与Master的关系还在
- 当Master重新启动,主从关系恢复如初
- Slave查看
- 将Slave1 shutdown,Master不动
- Slave2的主从关系不会有变化
- Slave1重新启动后,主从关系消失了,需要重新
slaveof 127.0.0.1 6379
进行数据同步 - 如果希望Slave挂/断掉重启后“再续前缘”,需进行Slave-server的配置
replicaof 127.0.0.1 6379
测试2 Master<Slave1<Slave2(Slave1是Slave2的Master)
- 上一个Slave可以是下一个Slave的Master,这样可以分担Master的写压力
- Slave2改变Master:
slaveof 127.0.0.1 6380
- 查看Slave1的主从信息变化:
info replication
- 目前从整体上看,数据完整性和之前“一主二仆”模式是一样的,只是现在Slave2是从Slave1同步数据,变成“薪火相传”模式,那么Slave1怎么分担Master的压力?继续操作..
- 将Master shutdown,模拟Master机器挂掉了,此时可以对Slave1
slaveof no one
,让Slave1“反客为主”新的Master(role有Slave变成Master),这样就可以对其进行写操作,并和Slave2继续主从关系 - 此时,原Master服务重启恢复,将成为单独的Master服务,被原Slave1、Slave2孤立在外。
- 然后,将Slave1重新挂给Master,恢复最原始的“一主二仆”关系,会发现Slave1和Slave2在Slave1“反客为主”时期写的数据消失了,而变成了Master的数据。由此可知Slave变更Master后,Slave的数据会先清空,然后同步为新的Master的数据
哨兵(sentinel)模式
说明
- 前面的测试中,当Master挂掉,还需要人为的将某个Slave转换为Master,而实际上机器挂掉可能发生在任意时刻,比如凌晨,所以不能依靠人为处理。
- 哨兵模式弥补了上面的缺点,达到所谓“无人值守”的效果。
- 效果1:使用哨兵模式,会另启动一个进程,对Master进行监控,如果监控到Master故障,则根据投票机制自动将某个Slave升级为新的Master(查看sentinel日志可以看到投票细节)。
- 效果2:哨兵模式将Slave1升级为Master后,如果原Master恢复,哨兵监控到后,会自动把原Master降级挂给Slave1,主从关系完全变更。
配置与测试
- 恢复“一主二仆”模式,一个Master(79),两个Slave(80、81)
- 新建sentinel配置文件
vi sentinel.conf
,内容:sentinel monitor master6379 127.0.0.1 6379 1
说明:sentinel monitor ...
指示sentinel监听后面机器上的Mastermaster6379
给后面要监听的Master取个名字127.0.0.1 6379
监听目标Master服务的ip和端口- 最后的数字m=1表示sentinel投票数,即当有n个sentinel(sentinel集群)认为这个Master挂了时,才会认为它真的挂了,然后进行故障迁移动作。这里是单机测试,所以n直接设置为1。
- 可以新行,监听多个主机Master
- 启动哨兵
redis-sentinel sentinel.conf 或者 redis-server sentinel.conf --sentinel
启动后可以看到日志:# Sentinel ID is 89568e210930ec9fe58e4cf856a5ef8e14501955 # +monitor master master6379 127.0.0.1 6379 quorum 1 * +slave slave 127.0.0.1:6380 127.0.0.1 6380 @ master6379 127.0.0.1 6379 * +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ master6379 127.0.0.1 6379
- 将Master shutdown,观察哨兵日志
# +sdown master master6379 127.0.0.1 6379 # +odown master master6379 127.0.0.1 6379 #quorum 1/1 # +new-epoch 1 # +try-failover master master6379 127.0.0.1 6379 # +vote-for-leader 89568e210930ec9fe58e4cf856a5ef8e14501955 1 # +elected-leader master master6379 127.0.0.1 6379 # +failover-state-select-slave master master6379 127.0.0.1 6379 # +selected-slave slave 127.0.0.1:6380 127.0.0.1 6380 @ master6379 127.0.0.1 6379 * +failover-state-send-slaveof-noone slave 127.0.0.1:6380 127.0.0.1 6380 @ master6379 127.0.0.1 6379 * +failover-state-wait-promotion slave 127.0.0.1:6380 127.0.0.1 6380 @ master6379 127.0.0.1 6379 # +promoted-slave slave 127.0.0.1:6380 127.0.0.1 6380 @ master6379 127.0.0.1 6379 # +failover-state-reconf-slaves master master6379 127.0.0.1 6379 * +slave-reconf-sent slave 127.0.0.1:6381 127.0.0.1 6381 @ master6379 127.0.0.1 6379 * +slave-reconf-inprog slave 127.0.0.1:6381 127.0.0.1 6381 @ master6379 127.0.0.1 6379 * +slave-reconf-done slave 127.0.0.1:6381 127.0.0.1 6381 @ master6379 127.0.0.1 6379 # +failover-end master master6379 127.0.0.1 6379 # +switch-master master6379 127.0.0.1 6379 127.0.0.1 6380 * +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ master6379 127.0.0.1 6380 * +slave slave 127.0.0.1:6379 127.0.0.1 6379 @ master6379 127.0.0.1 6380 # +sdown slave 127.0.0.1:6379 127.0.0.1 6379 @ master6379 127.0.0.1 6380
可以看出,哨兵监控到79Master挂掉了,然后投票确定,然后重新选举80为新的Master。 - 查看原Slave的主从信息,可以看出80Slave的role变成了Master
- 重启79Master,查看哨兵日志和主从关系
* +convert-to-slave slave 127.0.0.1:6379 127.0.0.1 6379 @ master6379 127.0.0.1 6380
从日志也能看出,哨兵对79进行了convert-to-slave操作