文章目录
Redis高可用方案
- “高可用性”(High Availability)通常来描述一个系统经过专门的设计,从而减少停工时间,而保持其服务的高度可用性。
- 单机的Redis是无法保证高可用性的,当Redis服务器宕机后,即使在有持久化的机制下也无法保证不丢失数据。通常采用Redis多机和集群的方式来保证Redis的高可用性。单进程+单线程 + 多机 (集群)
主从复制
- Redis支持主从复制功能,可以通过执行slaveof(Redis5以后改成replicaof)或者在配置文件中设置slaveof(Redis5以后改成replicaof)来开启复制功能。
主从配置
-
主Redis配置:无需特殊配置
-
从Redis配置:修改从服务器上的 redis.conf 文件:
# slaveof <masterip> <masterport> # 表示当前【从服务器】对应的【主服务器】的IP是192.168.10.135,端口是6379。 replicaof 127.0.0.1 6379
心跳检测
-
在命令传播阶段,从服务器默认会以每秒一次的频率向主服务器发送命令:
replconf ack <replication_offset> #ack :应答 #replication_offset:从服务器当前的复制偏移量
-
主要作用有三个:
- 检测主从的连接状态:检测主从服务器的网络连接状态,通过向主服务器发送INFO replication命令,可以列出从服务器列表,可以看出从最后一次向主发送命令距离现在过了多少秒。lag的值应该在0或1之间跳动,如果超过1则说明主从之间的连接有故障。
- 辅助实现min-slaves,Redis可以通过配置防止主服务器在不安全的情况下执行写命令。
min-slaves-to-write 3 (min-replicas-to-write 3 ) min-slaves-max-lag 10 (min-replicas-max-lag 10) 上面的配置表示:从服务器的数量少于3个,或者三个从服务器的延迟(lag)值都大于或等于10 秒时,主服务器将拒绝执行写命令。这里的延迟值就是上面INFOreplication命令的lag值。
- 检测命令丢失:如果因为网络故障,主服务器传播给从服务器的写命令在半路丢失,那么当从服务器向主服务器发送REPLCONF ACK命令时,主服务器将发觉从服务器当前的复制偏移量少于自己的复制偏移量,然后主服务器就会根据从服务器提交的复制偏移量,在复制积压缓冲区里面找到从服务器缺少的数据,并将这些数据重新发送给从服务器。(补发) 网络不断
哨兵模式
- 哨兵(sentinel)是Redis的高可用性(High Availability)的解决方案:
- 由一个或多个sentinel实例组成sentinel集群可以监视一个或多个主服务器和多个从服务器。
- 当主服务器进入下线状态时,sentinel可以将该主服务器下的某一从服务器升级为主服务器继续提供服务,从而保证redis的高可用性。
选举Leader Sentinel
- 当一个主服务器被判定为客观下线后,监视这个主服务器的所有Sentinel会通过选举算法(raft),选出一个Leader Sentinel去执行failover(故障转移)操作。
哨兵leader选举
- Raft协议是用来解决分布式系统一致性问题的协议
- Raft协议描述的节点共有三种状态:Leader, Follower, Candidate。
- term:Raft协议将时间切分为一个个的Term(任期),可以认为是一种“逻辑时间”。
选举流程:
- Raft采用心跳机制触发Leader选举,系统启动后,全部节点初始化为Follower,term为0。
- 节点如果收到了RequestVote或者AppendEntries,就会保持自己的Follower身份
- 节点如果一段时间内没收到AppendEntries消息,在该节点的超时时间内还没发现Leader,Follower就会转换成Candidate,自己开始竞选Leader。
- 一旦转化为Candidate,该节点立即开始下面几件事情:
- 增加自己的term。
- 启动一个新的定时器。
- 给自己投一票。
- 向所有其他节点发送RequestVote,并等待其他节点的回复
- 如果在计时器超时前,节点收到多数节点的同意投票,就转换成Leader。同时向所有其他节点发送AppendEntries,告知自己成为了Leader。
- 每个节点在一个term内只能投一票,采取先到先得的策略,Candidate前面说到已经投给了自己,Follower会投给第一个收到RequestVote的节点。
- Raft协议的定时器采取随机超时时间,这是选举Leader的关键。
Sentinel的leader选举流程
- 某Sentinel认定master客观下线后,该Sentinel会先看看自己有没有投过票,如果自己已经投过票给其他Sentinel了,在一定时间内自己就不会成为Leader。
- 如果该Sentinel还没投过票,那么它就成为Candidate。
- Sentinel需要完成几件事情:
- 更新故障转移状态为start
- 当前epoch加1,相当于进入一个新term,在Sentinel中epoch就是Raft协议中的term。
- 向其他节点发送 is-master-down-by-addr 命令请求投票。命令会带上自己的epoch
- 给自己投一票(leader、leader_epoch)
- 当其它哨兵收到此命令时,可以同意或者拒绝它成为领导者;(通过判断epoch)
- Candidate会不断的统计自己的票数,直到他发现认同他成为Leader的票数超过一半而且超过它配置的quorum,这时它就成为了Leader。
- 其他Sentinel等待Leader从slave选出master后,检测到新的master正常工作后,就会去掉客观下线的标识。
故障转移
- 当选举出Leader Sentinel后,Leader Sentinel会对下线的主服务器执行故障转移操作,主要有三个步骤:
- 它会将失效 Master 的其中一个 Slave 升级为新的 Master , 并让失效 Master 的其他 Slave 改为复制新的 Master
- 当客户端试图连接失效的 Master 时,集群也会向客户端返回新 Master 的地址,使得集群可以使用现在的 Master 替换失效 Master
- Master 和 Slave 服务器切换后, Master 的 redis.conf 、 Slave 的 redis.conf 和sentinel.conf 的配置文件的内容都会发生相应的改变,即, Master 主服务器的 redis.conf配置文件中会多一行 replicaof 的配置, sentinel.conf 的监控目标会随之调换
主服务器的选择
- 哨兵leader根据以下规则从客观下线的主服务器的从服务器中选择出新的主服务器。
- 过滤掉主观下线的节点
- 选择slave-priority最高的节点,如果由则返回没有就继续选择
- 选择出复制偏移量最大的系节点,因为复制偏移量越大则数据复制的越完整,如果由就返回了,没有就继续
- 选择run_id最小的节点,因为run_id越小说明重启次数越少