1.集群的扩容
就是集群的节点的上线和下线,因为槽和数据一一对应,又新节点的加入必定导致槽的变化,故数据也会产生迁移。
(1)先启动两个新的节点 6385和6386,但这两个节点还没有加入集群
(2)meet
(3)redis-trib命令来新加入一个节点和meet操作
(4)迁移槽的命令
(5)迁移槽的流程图
2.集群的收缩
(1)下线槽
(2)忘记节点(60s内如果与节点A关联的某一个节点没有忘记节点A,那么节点A无法被忘记)
(3)最后就是关闭不需要使用的节点即可
3. move重定向
槽所对应的我们连接的节点不一致,如果通过槽去查找对应的节点失败,返回moved
如:连接8000节点,8000节点的槽是0-100,数据<hello,world>在槽120上,那么我们在8000节点上如果不是集群模式连接就会报moved异常,如果是集群模式连接8000节点就会重定向到其他节点帮我们去执行该命令。
槽不命中,moved异常
4.ask重定向
ask重定向发生在扩容和缩容中,当我们连接8000节点发送数据时,原本归8000节点管理的数据<key,value>转移到了8001节点上,就会出现ask重定向一场。
它与moved重定向之间的不同之处在它是发生在数据迁移过程过。而moved异常发生在槽早已经迁移了或者该数据本来就不属于该槽。
5.mget在cluster中的使用
原来的思路:key1扫描redis中所有的节点,每个节点执行一次get操作
优化:在client端,key1-keyN对节点数hash取余,然后计算出每个节点的所有的key的集合,集合存在subKeys中,然后subkeys与对应的node建立一个pipeline,一次性将所有的数据发给对应的节点。
如果是单线程,那么n个pipeline需要n次网络时间(串行IO)
如果是多线程,那么n个pipeline通过n个线程发送只需要一个网络时间(并行IO)
hash_tag操作:
将所有的key合并起来,一起发给同一个节点(可能产生数据倾斜)
6.故障发现
通过ping/pong实现故障发现:
(1)主观下线:节点1给节点2发送ping超时,节点1就认为节点2主观下线
(2)客观下线:当认为节点1主观下线的节点数超过一半时,认为节点1客观下线
每个节点都护维持一个节点信息的表,表中记录所有的节点的故障信息,如果上面表示有半数的节点都认为节点1主观下线,那么节点1客观下线。当确定节点1客观下线以后就通知所有节点该消息
。
7.故障恢复
(1)资格审查:审查主节点的所有slave与master的断线时间,短线时间超过阈值的取消资格。
(2)准备选举阶段:所有通过(1)的节点会检查offset,如果offset最大的节点就会延迟最短的时间后产于选举。如图,rank=0偏移量最大,延迟1秒后参加选举,rank=2的偏移量最小,延迟时间最长。这样是为保证保存数据最完整的节点选举成功。
(3)选举投票:使用ruft协议选举新的master,很明显,偏移量大的节点开始选举的时间更早,也更有优势,当选举成功超过半数,选举就成功了,slave就可以替换master的工作了。
(4)替换主节点:首先使用slaveof no one的命令,然后撤销主节点的槽,替换主节点的槽,最后向集群广播成功转移故障。
8.缺陷
发布/订阅模式下,所有的节点都会受到相应的消息,消息传递带宽很大,不建议在大型机群中使用。
集群模式下读写分离实现很复杂,slave节点只可以通过readonly命令取去读数据(不适用readonly你直接去slave中读数据会重定向到master中去取数据),不可以写数据,不建议使用redis读写分离,不如扩大集群规模方便维护。需要自己去实现客户端维护slave的槽。
9.单机使用sentinel和cluaster的区别
如果不是容量上的需要使用sentinel性能就已经足够好了。而且cluster更加难以维护。