Redis Cluster知识点概括性整合

Redis Cluster知识点概括性整合

Redis分区方案

 redis的分区方案共有三种:客户端分区方案,代理分区方案,查询路由方案(cluster)

Redis Cluster框架

 redis采用去中心化的分布式结构框架,所有节点通过gossip协议相连,客户端只需直连其中一个节点即可进行访问。redis的所有数据保存在内存中,因此IO效率非常快,但是存储量有限,适合较小数据量的高性能操作和运算场景。

 redis cluster 采用哈希槽(hash slot)的方式,在集群中内置了16384(这个数量绝对固定),每个节点各自负责该总数的一个子集,并且各个节点负责的slot没有交集,当所有节点负责的包含所有的16384个槽,集群才能正常工作。

 redis不保证强一致性,主从间采用异步复制,如果写入数据过程中主节点挂了,从节点被提拔,则未写入的部分继续写入,已经写入的数据永久丢失。删除和增加节点只需要移动slot即可达成,无需停止服务

Redis的访问具体过程及端口

 访问或者存储redis的key时,需要先用CRC16算法计算出一个结果[0-32767],再对16384取模(CRC16(key)&16383),如果对应的slot在当前节点,就直接返回,否则返回负责这个slot的节点的ip和端口,以及-MOVED标识,再由客户端进行请求访问。

 redis的每个节点都需要开放两个端口(x,x+10000)较大的用作节点间通信,而较小的用于和客户端通信。

Gossip协议

 在redis环境下,gossip协议的工作流程可以看作一个消息源节点每秒随机向其他节点发送自己的数据包,再由接到的节点再次传播,最终在某一刻让所有可达的节点全部接收到消息。类似于烽火信号的传播(不局限于空间和距离为前提),谣言传播(点状态的改变随机引起其他点的状态改变并最终所有点趋向统一)。计算机网络中的泛洪和路由算法都属于gossip的范畴。在redis实际情况下,gossip通过PING-PONG机制实现,主要分为PING、PONG、MEET、UPDATE、PUBLISH、FAIL几种。每个节点都会频繁给其他节点发送PING(一秒十次,每次会选择5个最久没有通信的其他节点,如果发现通信延时过长,达到了cluster_node_timeout / 2,则立刻发送PING)消息,包含了自己的状态和自己维护的集群元数据,还带上了1/10其他节点的信息。通过相互PING进行数据交换更新,其他节点接收到PING后返回一个PONG的消息,包含了自己的状态等等。

 gossip:好处在于,元数据的更新比较分散,不是集中在一个地方,更新请求会陆陆续续,打到所有节点上去更新,有一定的延时,降低了压力; 缺点,元数据更新有延时,可能导致集群的一些操作会有一些滞后

 redis的持久化方法由aof、rdb、aof&rdb,aof会把每一次写操作追加记录于log文件中并把数据刷到磁盘里(有些类似hbase),但是aof文件大小随时间线性增长,如果需要以aof文件恢复数据将十分缓慢。rdb则是一种快照机制,每隔一段时间对数据做一次快照,保存于rdb文件中,但是如果数据量太大,进行快照保存完整的数据集的工作量将非常庞大。最新版本的redis采用aof和rdb的混合方案

 Gossip 算法又被称为反熵(Anti-Entropy),熵是物理学上的一个概念,代表杂乱无章,而反熵就是在杂乱无章中寻求一致,这充分说明了 Gossip 的特点:在一个有界网络中,每个节点都随机地与其他节点通信,经过一番杂乱无章的通信,最终所有节点的状态都会达成一致。每个节点可能知道所有其他节点,也可能仅知道几个邻居节点,只要这些节可以通过网络连通,最终他们的状态都是一致的,当然这也是疫情传播的特点。

 简单的描述下这个协议,首先要传播谣言就要有种子节点。种子节点每秒都会随机向其他节点发送自己所拥有的节点列表,以及需要传播的消息。任何新加入的节点,就在这种传播方式下很快地被全网所知道。这个协议的神奇就在于它从设计开始就没想到信息一定要传递给所有的节点,但是随着时间的增长,在最终的某一时刻,全网会得到相同的信息。当然这个时刻可能仅仅存在于理论,永远不可达。

Redis Cluster详细机制

 为了保证高可用性,redis至少应该拥有奇数个节点 每个节点拥有一个slave备份节点(从节点),因此至少需要六个节点,如果一个节点的从节点全挂掉了,集群会从其他节点的冗余从节点(指节点上的信息不唯一,在别的节点或从节点中都有备份,以防元数据的损失)中选取一个过渡给该节点,若是一个节点在备份节点全部挂掉的情况下他自己也挂掉了,那么整个集群都将停止工作(fail)。除此之外还有两个集群fail的条件:超过半数以上的主节点挂掉,则无论是否有备份节点,集群都进入fail状态;或者没有从节点的任意主节点挂掉了,集群进入fail(和第一种情况的区别是从节点个数少于节点个数,不够为每一个节点都分配从节点)

 如何判断节点挂掉了->当集群中一半以上的节点给该节点发送ping消息而没有收到回应,就判断节点宕机,此时集群会从该节点的备份节点中发起竞选,数据越新的节点越有可能成为新的节点。当节点决定参选,将会向其他节点发送消息(类似拉票),当参选节点收到半数以上的同意信息,就竞选成功,会立刻发起广播,让整个集群更新信息,原来被代替的节点恢复正常后重新成为备份节点。

epoch(纪元)
 currentEpoch,根据集群状态变更而递增的版本号(针对整个集群),集群创建时都为0,当收到来自其他节点的包时,检查位于消息头部的currentepoch,如果currentepoch大于当前版本,就进行更新,最终强制集群的所有节点更新版本信息。当集群的状态发生了改变,某个节点为了执行一些动作而征求其他节点同意时,就会增加currentepoch(slave、master的故障转移)。
 configEpoch,根据节点负责槽位信息变更而递增的版本号(针对每个master-slave),每个节点向其他节点发送包时会附带其configepoch,以及其负责的哈希槽(slot),其他节点收到包后,记录到对应的节点属性中。configepoch属性主要用于确保最新的哈希槽负责信息。举个例子,节点a负责slot1,并向外发送包,节点c收到包,发现自己没有记录slot1的负责节点,更新server.cluster->slot[1]=A,并记录configepoch,此后c又收到来自b的包,发现b也称自己负责slot1,此时就需要比较各自的configepoch,发现b的更大,b发来的信息才是当前最新的状况,因此将slot1的负责节点设置为b。(slave选举为master时也会自增configepoch并广播,让整个集群知道自己正在负责相关slot)

参考:
https://yq.aliyun.com/articles/711825
https://www.cnblogs.com/liyasong/p/redis_jiqun.html
http://www.mamicode.com/info-detail-2452322.html
https://blog.csdn.net/lidiya007/article/details/53289535(较深)
https://www.jianshu.com/p/c26697412d72

posted @ 2020-07-27 16:47  -拂石-  阅读(246)  评论(0)    收藏  举报