Redis的高可用方案
主从复制
Redis支持主从复制模式,可以通过执行slaveof(redis5以后改成replicaof)或者在配置文件中设置slaveof 来开始复制功能
模式
一主一从:
一主多从:
主从配置
主机无需特殊配置
从redis需要修改redis.conf
#表示当前服务器是哪个主服务器的
replicaof 127.0.0.1 6379
作用
读写分离:
一主多从,主从同步
主负责写,从负责读
提升Redis的性能和吞吐量
主从数据一致性问题
数据容灾
从机是主机的备份
主机宕机,从机可读不可写
默认情况下主机宕机后,从机不可为主机
利用哨兵可以实现主从切换
原理与实现
复制流程
- 保存主节点信息,当客户端向从服务器发送slaveof(replica of) 主机地址(127.0.0.1)端口6379时:从服务器将主机ip(127.0.0.1)和端口(6379)保存在redisServer的masterhost和masterport种。从服务器将向发送slaveof 命令的的客户端返回OK,表明复制指令已经被接收,而实际复制工作实在OK返回之后执行
- 建立socker链接,slaver与master建立socket链接,slaver关联文件事件处理器,该处理器接收RDB文件,接收master传播来的命令
主服务器accept从服务器socket连接后,创建相应的客户端状态,将挡雨从服务器是主服务器的client端
-
发送ping命令,slaver向master发送ping命令:检测socket的读写状态,检测matser能否正常处理
master响应:发送pong命令,说明正常,返回错误,说明master不正常,timeout,说明网络超时
-
主从连接上之后,进行权限验证
-
身份验证之后,从服务器将执行命令REPLCONF listening-port,向主服务器发送从服务器的监听端口信息。
-
同步数据:分全量和增量
2.8之前:同步sync和命令传播(command propagate)
2.8之后,使用psync命令,具备完整同步和部分重同步模式,除此之外都是增量同步
只有第一次连接上主机是全量同步,断线重连有可能触发全量同步也有可能是增量同步(比较runid)
全量:master 的rdb->slaver+ 缓冲区命令
增量:缓冲区命令
9. 命令传播:数据同步完成后,主从服务器就进入命令传播阶段,主服务器就会进入命令传播阶段,主服务器只要将自己执行的写命令发送给从服务器,而从服务器只要一直执行并接受主服务器发来的写命令
心跳检测
在命令传播时候,从服务器默认会每一秒的频率向主服务器发送命令
主要作用有3个:
检测主从连接状态、
辅助实现min-slaves
min-slaves-to-write 3 (min-replicas-to-write 3 )
min-slaves-max-lag 10 (min-replicas-max-lag 10)
上面的配置表示:从服务器数量小于3个,或者3个从服务器的延迟(lag) 值都大于或等于10秒时,主服务器将拒绝写的命令
检测命令丢失:网络断了找到偏移量补发
哨兵模式
由一个或多个sentinel实例组成sentinel集群可以监视一个或多个主服务器或多个从服务器继续提供服务,从而保证redis高可用性
执行流程
-
启动并初始化sentinel sentinel是一个特殊的服务器,不会进行持久化,sentinel实例启动后,会创建两个连向主服务器的网络连接
命令链接:发送命令并接收响应
订阅链接:用于订阅主服务器的sentinel-hello频道
-
获取主服务器信息
-
获取从服务器信息
-
以订阅的方式向主从服务器发送消息
-
接受来自主服务器和从服务器的频道信息
-
检测主管下线状态,检测客观下线状态
-
选举leader sentinel
哨兵Leader选举
raft协议,follower,leader,candidate
一开始都是follower,没有收到requestVote变candidate发requestvote
1、某Sentinel认定master客观下线后,该Sentinel会先看看自己有没有投过票,如果自己已经投过票
给其他Sentinel了,在一定时间内自己就不会成为Leader。 2、如果该Sentinel还没投过票,那么它就成为Candidate。 3、Sentinel需要完成几件事情:
更新故障转移状态为start
当前epoch加1,相当于进入一个新term,在Sentinel中epoch就是Raft协议中的term。
向其他节点发送 is-master-down-by-addr 命令请求投票。命令会带上自己的epoch。
给自己投一票(leader、leader_epoch) 4、当其它哨兵收到此命令时,可以同意或者拒绝它成为领导者;(通过判断epoch) 5、Candidate会不断的统计自己的票数,直到他发现认同他成为Leader的票数超过一半而且超过它配
置的quorum,这时它就成为了Leader。 6、其他Sentinel等待Leader从slave选出master后,检测到新的master正常工作后,就会去掉客观下
线的标识
故障转移
选出leader sentinel 后,leader sentinel会对下线的服务器执行故障转移,将失效master的slave升级为master,当客户端连接master时候,集群会返回新的matser地址。切换后,对应的conf文件都会变化
主服务器的选择
- 过滤掉主管下线的节点
- 选择slave-priority最高的节点,如果有则返回,没有就继续
- 选择出复制偏移量最大的节点,因为复制偏移量越大则数据复制越完整,如果有就返回,没有就继续
- 选择run_id最小的节点,因为run_id越小说明重启次数越小
集群与分区
分区的意义
分区是将数据放在多个redis实例上,以便每个实例只包含一部分数据
- 性能的提升:单机redis的网络I/O能力和计算资源是有限的,将请求分散到多台机器,充分利用多台机器的计算能力有利于总体服务提升
- 存储能力横向扩展
分区的方式
根据分区键Id进行分区,可以范围分区,可以哈希分区、一致性哈希
官方cluster分区
方案采用去中心化的方式,包括:sharding(分区)、replication(复制)、failover(故障转移),成为rediscluster
特点:
- 去中心化,rediscluster由多个redis节点组成,是一个P2P无中心节点的集群架构,依靠GOSSIP协议传播的集群
- Gossip协议:一个通信协议,一种传播消息的方起源于:病毒传播
- slot redis-cluster把所有物理节点映射到0-16383个槽上,基本采用平均分配和连续分配的方式,cluster负责维护节点和slot槽的对应关系 value->slot->节点
redisCluster的优势:
- 高性能
- 可扩展,可不停机扩展
- 原生,不需要其他代理工具,跟单机redis操作几乎无区别
分片
不同节点分组服务于相互无交集的分片(sharding), Redis Cluster不存在单独的proxy或配置服务器,所以需要将客户端路由到目标的分片
moved 重定向:执行命令,如果不在当前节点,会转发到在的节点
ask重定向:
对集群扩容,需要对槽数据迁移,ask转给客户端
JedisCluster 客户端
操作redis集群
迁移
扩容:
重新给新增的节点分配槽和数据
./redis-cli --cluster reshard 127.0.0.1:7007
redisCluster一些特性
- 故障转移:集群种每个节点都会定期每秒的向及群众其他节点发送ping消息,如果在一定时间内,发送ping的节点A没有收到节点B的pong命令,则A将B置为Pfail,会通知其他节点,超过1/2数目,则任务B客观下线
- 从节点选举:raft,每个节点根据自己对master复制的offset,来设置一个选举时间,offset越大的从节点,选举时间越靠前,优先选举
- rediscluster失效:集群种半数以上主节点宕机了,主节点的从节点也都宕机了
- 变更通知,当slaver收到过半数master同意,会成为新的master,此时会议最新的epoch通过pong消息广播自己成为master
- 主从切换:手动/自动
- 副本漂移: