1.一种基于Gossip通信协议和Raft选举算法的优化方法,是应用于由N×(n+1)个节点组成的Redis集群中,所述节点是运行在集群模式下的Redis服务器,并分为N个主节点和N×n个从节点,任意一个主节点分别对应于n个从节点,由一个主节点及其对应的n个从节点构成一个分片;其特征是,所述优化方法按如下步骤进行:步骤1、全局定义:
定义所述N个主节点构成的主节点集合为{M1,M2,…,Mi,…,MN},Mi表示第i个主节点;1≤i≤N;
定义所述第i个主节点Mi的从节点集合为{Si1,Si2,…,Sij,…,Sin},Sij表示第i个主节点Mi所对应的第j个从节点;1≤j≤n;
定义Redis集群中的所有节点集合为{N1,N2,…,Nk,…,NN×(n+1)},Nk表示第k个节点,1≤k≤N×(n+1);
定义保存所述第k个节点Nk详细状态信息的结构体为第k个状态结构体CNk;
定义保存并维护所述第k个节点Nk对Redis集群认知的结构体为第k个认知结构体CSk,所述第k个认知结构体CSk中所保存的信息包括:当前纪元、上一次投票纪元和Redis集群中所有节点的状态结构体;定义第k个认知结构体CSk中的当前纪元记为CEk、上一次投票纪元记为LEk、所有节点的状态结构体所组成的链表为NOk;
定义任意第p个节点Np和第q个节点Nq之间周期性的通信消息为PING/PONG消息;1≤p,q≤N×(n+1);p≠q;
所述第p个节点Np发送的PING/PONG消息中携带自身的状态信息和相应的Gossip单元;
定义所述Gossip单元包含w条Gossip消息;每条Gossip消息对应一个其他节点的状态信息,通过Redis集群中的PING/PONG消息传播,所述第p个节点Np更新自身的认知结构体CSp;
定义节点间的通信超时时间为T;
定义所述Redis集群中的所有节点分为三种状态,包括:在线状态、疑似下线状态、下线状态;
在线状态表示第p个节点Np在发送PING消息后,在通信超时时间T内收到接收第q个节点Nq的PONG消息,则第q个节点Nq认为第p个节点Np处于在线状态;
疑似下线状态表示第p个节点Np在发送PING消息后,在通信超时时间T内没有收到接收第q个节点Nq的PONG消息,则第p个节点Np认为第q个节点Nq处于疑似下线状态;
下线状态表示第p个节点Np发现超过 个主节点认为第q个节点Nq处于疑似下线状态,则第p个节点Np认为第q个节点Nq处于下线状态,并将第q个节点Nq的下线消息广播给其他节点;
定义在Redis集群中第k个节点Nk的链表NOk中处于疑似下线状态的节点数为uk;
定义选取次数为r,并初始化r=1;
步骤2、第k个节点Nk每秒钟固定向其他m个接收节点发送PING消息;
步骤3、基于Gossip通信协议优化方法对m的值和接收节点的选取方式进行更改:步骤3.1、令
步骤3.2、第k个节点Nk在Redis集群中未选取的节点内第r次随机选取一个预接收节点,判断所述预接收节点与第k个节点Nk之间中断PING/PONG通信的时间是否超过T/2,若超过,则将所述预接收节点作为接收节点;否则,丢弃所述预接收节点;
步骤3.3、将r+1赋值给r,并返回步骤3.2执行,直到r=m+1为止,从而获得m1个接收节点;
步骤3.4、判断m1=m是否成立,若成立,则执行步骤3.8,否则执行步骤3.5;
步骤3.5、初始化r=1;
步骤3.6、第k个节点Nk在Redis集群中未选取的节点内第r次随机选取一个接收节点;
步骤3.7、将r+1赋值给r,并返回步骤3.6执行,直到r=m-m1+1为止,从而获得m-m1个接收节点;
步骤3.8、第k个节点Nk向m个接收节点发送PING消息;
步骤4、主节点M′故障后,第k个节点Nk向主节点M′发送PING消息,并在通信超时时间T内未收到主节点M′的PONG消息,则第k个节点Nk认为主节点M′处于疑似下线状态,并将所述主节点M′的状态信息作为一条Gossip消息添加到PING/PONG消息的Gossip单元中,并发送给其他节点,从而告知其他节点主节点M′处于疑似下线状态;
步骤5、通过PING/PONG消息的传播,主节点M′的疑似下线消息会在Redis集群中扩散,基于Gossip通信协议的优化方法对w的值和Gossip单元的选取方式进行更改:步骤5.1、令wk=w+uk;
步骤5.2、第k个节点Nk标记uk个处于疑似下线状态的节点,并将所述uk个节点的状态信息优先添加到自身PING/PONG消息的Gossip单元中;
步骤5.3、第k个节点Nk在未选取的节点中随机选取w个节点,并将所述w个节点的状态信息优先添加到自身PING/PONG消息的Gossip单元中;从而共选取w+uk个节点作为wk个Gossip消息添加到Gossip单元中;
步骤6、通过PING/PONG消息的传播,第p个节点Np发现超过 个主节点认为主节点M′处于疑似下线状态,则第p个节点Np认为主节点M′处于下线状态,并将主节点M′的下线消息广播给其他节点;从而使得主节点M′处于下线状态的消息在Redis集群中传播;
步骤7、假设发生故障的主节点M′所对应的主节点为第i个主节点Mi;则当从节点集合{Si1,Si2,…,Sij,…,Sin}接收到的PING/PONG消息中包含主节点M′处于下线状态的信息时,第j个从节点Sij向所有节点发起投票请求;
步骤8、第k个节点Nk接收到所述第j个从节点Sij的投票请求,则基于Raft选举算法对投票方式进行更改:步骤8.1、第k个节点Nk将认知结构体CSk上的当前纪元CEk和上一次投票纪元LEk保存到链表NOk的所有状态结构体中;从而使得所有状态结构体中均保存各自的当前纪元和上一次投票纪元;
步骤8.2、若第k个节点Nk是主节点,则获得发生故障的主节点M′在所有节点中所在的位置z后,第k个节点Nk通过认知结构体CSk保存的第z个状态结构体CNz上的当前纪元和上一次投票纪元来判断是否发送支持票给第j个从节点Sij;若第k个节点Nk是从节点,则第k个节点Nk对投票请求不做任何处理;
步骤9、当第j个从节点Sij接收到 个主节点的支持票时,第j个从节点Sij升为新的主节点,代替原来主节点的功能,并通过广播PING消息告知所有的其他节点,从而使得Redis集群中所有节点得知第j个从节点Sij升为主节点;
步骤10、Redis集群恢复成功。