基于Gossip通信协议和Raft选举算法的优化方法与流程

文档序号:11147681阅读:1657来源:国知局
基于Gossip通信协议和Raft选举算法的优化方法与制造工艺

本发明涉及非关系型的数据库技术领域,具体地说是一种基于Gossip通信协议和Raft选举算法的优化方法。



背景技术:

Redis集群是由N×(n+1)个Redis服务器节点构成的分布式集群,服务器节点分为N个主节点和N×n个从节点,一个主节点对应n个从节点,主节点负责对处理槽以及相应的客户操作,从节点复制备份主节点的数据。在主节点故障后,Redis集群通过Gossip通信协议来判断故障的主节点处于下线状态,并停止接收客户端的请求;随后加入相应的故障转移过程,对应的从节点在通过Raft选举算法获得个主节点的支持票后,升为新的主节点,代替原先主节点的功能,使得集群恢复成功。

作为一种分布式集群,稳定性和可靠性非常重要,但是目前的Redis集群在主节点故障后,恢复时间不稳定且耗时较长,甚至无法成功恢复,并且随着故障主节点数目的增加,Redis集群的恢复时间增长很快;当用户执行比较耗时的操作时,Redis集群会产生错误的主从切换。这些都与Redis集群现有的Gossip通信协议和Raft选举算法的具体实现有关,其中Gossip通信协议是一种最终一致性算法,不能保证在某个时间点使整个集群的所有节点达到一致的状态;Raft选举算法是一种基于日志副本同步的一致性算法,可分成主节点选举,日志同步和安全提交。



技术实现要素:

本发明是为了克服现有技术存在的不足之处,提供一种基于Gossip通信协议和Raft选举算法的优化方法,以期能克服现有Redis集群的上述缺陷,从而能在不影响Redis集群的吞吐量和时延的基础上,缩短Redis集群的恢复时间,提升Redis集群的可靠性和稳定性。

本发明为达到上述发明目的,采用如下技术方案:

本发明一种基于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集群恢复成功。

与已有技术相比,本发明有益效果体现在:

1、本发明提出并实现一种基于Gossip通信协议的优化方法,在不影响Redis集群性能的情况下,使Redis集群在较短时间内从故障中恢复,Redis集群恢复过程的效率提升了30%,有效降低了节点故障对Redis集群造成的损失;相对于现有的Redis集群,优化后的Redis集群在稳定性和可靠性上有显著提升;

2、本发明提出并实现一种基于Raft选举算法的优化方法,将来自不同分片的投票请求进行单独的投票,使得一个主节点可以对不同分片的节点进行投票,有效规避了重新投票的情况,从而提升了集群的稳定性和可靠性。

附图说明

图1为节点之间PING/PONG消息通信过程示意图;

图2为Redis集群成功恢复的全过程示意图;

图3为恢复阶段详细示意图;

图4为现有Redis集群的结构体表示示意图;

图5为优化后Redis集群的数据结构表示示意图。

具体实施方式

下面结合附图通过具体实施例对本发明基于Gossip通信协议和Raft选举算法的优化方法做进一步的详细说明。

本实施例中,一种基于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个状态结构体CNk保存的信息包括节点的名称、所管理的槽数量、所属分片的主节点名称和下线报告;定义在第k个状态结构体CNk上节点的名称为NAk;定义在第k个状态结构体CNk上所管理的槽数量为SLk;定义在第k个状态结构体CNk上所属分片的主节点名称为NSk;定义在第k个状态结构体CNk上的下线报告为FRk

定义保存并维护第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、图1给出了Redis集群中PING/PONG消息通信的大致过程,此步骤中的发送节点为第k个节点Nk,第k个节点Nk每秒钟固定向其他m个接收节点发送PING消息;

步骤3、基于Gossip通信协议优化方法对m的值和接收节点的选取方式进行更改,是对图1中发送节点的发送PING消息的实现过程进行更改:

步骤3.1、m的值与下线判断的耗时成反比关系,并且为了适应不同的集群,优化方法将参数m设置成和集群主节点数目相关的参数;令即每秒钟选取个接收节点发送PING消息:在的时间内节点可以与集群中所有的其他节点至少通信一次,将接收节点平均到每秒钟去,这样可以避免在最后时刻有较多的未通信节点;这种设置既能保证原来的通信量,又能对节点间的消息发送在时间分布上做一个均衡;

步骤3.2、对于m个接收节点的选取,最多在2×m次循环中选出,第k个节点Nk在Redis集群中未选取的节点内第r次随机选取一个预接收节点,判断预接收节点与第k个节点Nk之间中断PING/PONG通信的时间是否超过T/2,若超过,则将预接收节点作为接收节点;否则,丢弃预接收节点;

步骤3.3、将r+1赋值给r,并返回步骤3.2执行,直到r=m+1为止,从而获得m1个接收节点,这是前m次循环;

步骤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个接收节点,r的最大值为m;

步骤3.8、第k个节点Nk向m个接收节点发送PING消息,这样既能尽可能得选取与第k个节点Nk之间中断PING/PONG通信时间超过T/2的接收节点,也能减低选取接收节点造成的性能开销;

步骤4、图2以主节点M′故障为例,展示主节点下线恢复的整个过程,分为疑似下线阶段、下线阶段和恢复阶段;图2中疑似下线阶段:第k个节点Nk向发生故障的主节点M′发送PING消息,并在通信超时时间T内未收到主节点M′的PONG消息,则第k个节点Nk认为主节点M′处于疑似下线状态,并将主节点M′的状态信息作为一条Gossip消息添加到PING/PONG消息的Gossip单元中,并发送给其他节点,从而告知其他节点主节点M′处于疑似下线状态;

步骤5、通过PING/PONG消息的传播,主节点M′的疑似下线消息会在Redis集群中扩散,基于Gossip通信协议的优化方法对w的值和Gossip单元的选取方式进行更改,是对图1中接收节点的回复PONG消息的实现过程进行更改:

步骤5.1、令wk=w+uk

步骤5.2、第k个节点Nk标记uk个处于疑似下线状态的节点,并将uk个节点的状态信息优先添加到自身PING/PONG消息的Gossip单元中,此举的目的是为了增加Gossip单元中疑似下线的节点状态信息的比例;

步骤5.3、第k个节点Nk在未选取的节点中随机选取w个节点,并将w个节点的状态信息优先添加到自身PING/PONG消息的Gossip单元中;从而共选取w+uk个节点作为wk个Gossip消息添加到Gossip单元中,由步骤3和步骤5组成的基于Gossip通信协议的优化方法可以尽量加快所有节点的疑似下线消息在Redis集群内的传播速度;当主节点的疑似下线消息能够快速的在Redis集群内传播,便可以有效减少Redis集群检测主节点从的疑似下线阶段到的下线阶段的时间,如图2中所示;

步骤6、图2中下线阶段:通过PING/PONG消息的传播,第p个节点Np发现超过个主节点认为主节点M′处于疑似下线状态,则第p个节点Np认为主节点M′处于下线状态,并将主节点M′的下线消息广播给其他节点;从而使得主节点M′处于下线状态的消息在Redis集群中传播;

步骤7、步骤7~10是图2中恢复阶段,并且图3展示了恢复阶段的详细过程,假设发生故障的主节点M′所对应的主节点为第i个主节点Mi;则当从节点集合{Si1,Si2,…,Sij,…,Sin}接收到的PING/PONG消息中包含主节点M′处于下线状态的信息时,第j个从节点Sij向所有节点发起投票请求;

步骤8、第k个节点Nk接收到第j个从节点Sij的投票请求,则基于Raft选举算法对投票方式进行更改:

步骤8.1、第k个节点Nk将认知结构体CSk如图4所示,将第k个节点Nk将认知结构体CSk上的当前纪元CEk和上一次投票纪元LEk保存到链表NOk的所有状态结构体中;从而使得所有状态结构体中均保存各自的当前纪元和上一次投票纪元,如在图5中NOk的CNz上的ICEz和ILEz;1≤z≤N×(n+1);

步骤8.2、若第k个节点Nk是主节点,则获得发生故障的主节点M′在所有节点中所在的位置z后,第k个节点Nk通过认知结构体CSk保存的第z个状态结构体CNz上的当前纪元和上一次投票纪元来判断是否发送支持票给第j个从节点Sij,即通过图5中CNz上的当前纪元ICEz和上一次投票纪元ILEz来判断是否投票给第j个从节点Sij;若第k个节点Nk是从节点,则第k个节点Nk对投票请求不做任何处理;1≤z≤N×(n+1);由步骤8构成的基于Raft选举算法的优化方法将当前纪元CEk和上一次投票纪元LEk分散保存每个节点的状态结构体中,能对来自不同分片的投票请求进行单独的比较,从而成功规避图3中重新投票的情况;

步骤9、当第j个从节点Sij接收到个主节点的支持票时,第j个从节点Sij升为新的主节点,代替原来主节点的功能,并通过广播PING消息告知所有的其他节点,从而使得Redis集群中所有节点得知第j个从节点Sij升为主节点。

步骤10、Redis集群恢复成功。

当前第1页1 2 3 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1