wangxiaoxue 2019-12-23
Redis专题地址:https://www.cnblogs.com/hello-shf/category/1615909.html
SpringBoot读源码系列:https://www.cnblogs.com/hello-shf/category/1456313.html
Elasticsearch系列:https://www.cnblogs.com/hello-shf/category/1550315.html
数据结构系列:https://www.cnblogs.com/hello-shf/category/1519192.html
在redis3.0之前,如果想搭建一个集群架构还是挺复杂的,就算是基于一些第三方的中间件搭建的集群总感觉有那么点差强人意。或者基于sentinel哨兵搭建的主从架构在高可用上表现又不是很好,尤其是当数据量越来越大,单纯主从结构无法满足对性能的需求时,矛盾便产生了。
随着redis cluster的推出,这种海量数据+高并发+高可用的场景真正从根本上得到了有效的支持。
在redis cluster集群内部通过gossip协议进行通信,集群元数据分散的存在于各个节点,通过gossip进行元数据的交换。
不同于zookeeper分布式协调中间件,采用集中式的集群元数据存储。redis cluster采用分布式的元数据管理,优缺点还是比较明显的。
在redis中集中式的元数据管理类似sentinel主从架构模式。集中式有点在于元数据更新实效性更高,但容错性不如分布式管理。gossip协议优点在于大大增强集群容错性。
redis cluster集群中单节点一般配置两个端口,一个端口如6379对外提供api,另一个一般是加1w,比如16379进行节点间的元数据交换即用于gossip协议通讯。
gossip协议包含多种消息,如ping pong,meet,fail等。
meet:集群中节点通过向新加入节点发送meet消息,将新节点加入集群。 ping:节点间通过ping命令交换元数据。 pong:响应ping。 fail:某个节点主观认为某个节点宕机,会向其他节点发送fail消息,进行客观宕机判定。
主观宕机和客观宕机:
某个节点会周期性的向其他节点发送ping消息,当在一定时间内未收到pong消息会主观认为该节点宕机,即主观宕机。然后该节点向其他节点发送fail消息,其他超过半数节点也确认该节点宕机,即客观宕机。十分类似sentinel的sdown和odown。
客观宕机确认后进入主备切换阶段及从节点选举。
节点选举:
检查每个 slave node 与 master node 断开连接的时间,如果超过了 cluster-node-timeout * cluster-slave-validity-factor,那么就没有资格切换成 master。
每个从节点,都根据自己对 master 复制数据的 offset,来设置一个选举时间,offset 越大(复制数据越多)的从节点,选举时间越靠前,优先进行选举。
所有的 master node 开始 slave 选举投票,给要进行选举的 slave 进行投票,如果大部分 master node(N/2 + 1)都投票给了某个从节点,那么选举通过,那个从节点可以切换成 master。
从节点执行主备切换,从节点切换为主节点。
hash slot即hash槽。redis cluster采用的正式这种hash槽算法实现的寻址。
在redis cluster中固定的存在16384个hash slot。
hash slot = CRC16(key)%16384;
#CRC16算法可以简单的理解为一种hash算法。详见度娘。
这样我们就能找到key对应的hash slot。其实按照我的理解,hash slot就是在寻址和节点间加了一层映射关系。当节点动态变化,只需要改变hash slot ==> 节点的映射,然后只需要迁移指定slot到新添加的节点即可。既减少了hash寻址带来的数据全量迁移问题,相对一致性hash也使得负载均衡效果更加明显。
如上图,如果我们有三个节点。redis cluster初始化时会自动均分给每个节点16384个slot。
当增加一个节点4,只需要将原来node1~node3节点部分slot上的数据迁移到节点4即可。在redis cluster中数据迁移并不会阻塞主进程。对性能影响是十分有限的。总结一句话就是hash slot算法有效的减少了当节点发生变化导致的数据漂移带来的性能开销。
更多分布式寻址算法可参考:https://www.cnblogs.com/hello-shf/p/12079986.html
相比Sentinel主从架构,redis cluster中各个节点是对等的,类似elasticsearch的节点对等原理。
节点对等是我从elasticsearch copy过来的概念,但是用在这里还是很合理的。
Sentinel主从架构我们都知道只能搭建出来一个主从的架构(当然从还可以作为其它从的主),比较适合读写分离,原则上没有实现海量数据的分片。而Redis正是弥补了Sentinel无法实现海量数据的高可用,Redis cluster通过分片实现海量数据+高可用的高并发架构。
假如有100个数据,在sentinel中主节点完全存储100条数据,而在Redis cluster中通过hash slot将数据分片,平均分布在多个节点上,实现了海量数据的分片。原则上来说,Redis cluster才是真正的分布式架构。
有关Sentinel可参考:https://www.cnblogs.com/hello-shf/p/12072330.html
如有错误的地方还请留言指正。
原创不易,转载请注明原文地址:https://www.cnblogs.com/hello-shf/p/12080123.html
参考文献:
https://github.com/hello-shf/advanced-java