JGroups协议初探

本文并不试图阐明所有JGroups协议,只针对部分工程中用到的协议做通俗易懂的阐述。关于完整的JGroups协议请参见:
http://www.jgroups.org/manual4/index.html#protlist

发现协议(PING、MPING)

PING\MPING发现协议用于发现是否有其他节点加入指定名称的通道。一般来讲,PING协议运行在UDP之上,而MPING运行在TCP之上,二者机制类似。
PING\MPING协议用于动态节点发现,每个节点对PING消息的反馈消息包括协调者的地址和自己的地址,PING消息发送后等待指定时间(timeout属性)或指定数量的节点(num_initial_members属性)回复后,根据反馈消息确定协调者并发送JOIN消息。如果没有收到任何反馈,会认为自己是集群中第一个节点为协调者。

错误检测协议(FD_SOCK、FD_ALL、VERIFY_SUSPECT)

错误探测协议用来发现集群中发生错误的节点,当某一个节点发生错误被探测到时,会发送SUSPECT消息到所有节点。注意,SUSPECT只是通知其他节点,某个节点当前状态时可疑的。SUSPECT消息仅由coordinator节点接收(GMS协议处理),其他节点忽略该消息。

FD_SOCK

FD_SOCK协议基于群组成员创建的TCP Socket完成错误检测,集群中的任何一个节点都连接到它相邻的下一节点(如A->B->C->A),由此形成了一个套接字环。
当集群节点数量超过1个时,JGroups将启动pinger线程。pinger线程连接其右侧的邻居,并等待socket关闭(通过read堵塞接口)。当read接口发生IOException时,认定其邻居为SUSPECT状态。
该协议实现简单,并且不会带来额外的流量开销。但当服务器挂起或路由器崩溃时,并不会检测到socket关闭,检测失效(准确描述应该是:在TCP的keepalive检测超时后检测到)。

FD_ALL

FD_ALL协议基于简单的心跳协议,每个节点周期性的发送组播心跳。同时每个节点维护了一份完整的集群节点列表(除了自身节点),当收到来自节点P的心跳数据时,更新节点P的时间到当前时间。节点每个一定周期检测哪些过期的节点(时间长期未更新的节点),并发其SUSPECT流程。

VERIFY_SUSPECT

VERIFY_SUSPCET协议通过ping的方式再次确认可疑节点是否已终止。如已终止,则向上发送SUSPECT通知,将该节点移除;否则,直接丢弃SUSPECT消息。
默认情况下,向SUSPECT节点发送一个确认心跳消息,等待2秒钟。如果SUSPECT节点响应则丢弃SUSPECT消息,如无响应则认定节点丢失,向上发送SUSPECT通知。

合并协议(MERGE3)

如果网络异常发生,集群可能被分割成多个区域而形成多个集群(多个协调者)。合并协议负责将分割成的多个区域重新合并成一个集群(通过多个协调者之间的沟通)。
在MERGE3协议中,所有节点周期性的发送INFO消息,消息内容包括:地址信息(UUID),逻辑名,物理地址和ViewId。
ViewId用于查看集群成员内部间是否存在意见分歧:每个coordinator周期性的查看目前收到的INFO消息,并检查是否存在任何的不一致。如果存在不一致,将地址(UUID)最小的一个当作merge leader,这确保同一时刻只有一个merge leader。随后,merge leader收集到完整的信息,并发送MERGE请求给GMS,由GMS完成真正的MERGE动作。

群组成员关系协议(pbcast.GMS)

GMS即群组成员关系协议,该协议时JGroups协议栈中的重要协议,它维护者一个活着节点的列表。GMS负责群组成员加入和离开群组的请求,同时它也处理错误探测协议发送的SUSPECT协议。

消息稳定性协议(pbcast.STABLE)

为了处理可能的重发请求,节点需保存收到的message,直到集群中所有的节点都收到了该消息。消息稳定性(message stability)是指:对于给定的消息M,M可以被集群中的每个节点收到。
但是如果我们永远保存接收到的消息,则我们会面临内存溢出的问题。分布式垃圾回收协议负责周期性的释放所有节点上已经被所有节点收到的消息,从而达到回收各个节点上内存的目的。

可靠性协议(pbcast.NAKACK2、UNICAST3)

NAKACK2

NAKACK2协议保证多播传输的可靠性,是NAKACK的演进版本,二者实现的功能相同,但NAKACK2更快、占用的内存更小、定时触发的任务更少等特点。
NAKACK2协议用于保证传输的可靠性和FIFO顺序:

  • 消息可靠性:保证了一个消息会被收到,否则接收者会要求重传
  • FIFO:保证了从发送者发过来的所有消息会以相同顺序到达接收方

在这种协议下,每个消息绑定一个序列号,消息接收者根据序列号确保消息按正确的顺序传递。如果接收者发现了一个序列号的缺失,接收者安排一个周期性的任务去要求发送者重新发送该序列号的消息,当缺失的序列号的消息收到,则任务取消。典型配置项如下:


max_xmit_size:确定捆绑重发消息的大小。如果很多消息需要被重发,这些重发消息可能被捆绑成一个大消息然后重发。
use_mcast_xmit:确定是否重发消息给整个集群,还是只重发消息给消息的发送者。
retransmit_timeout:重发请求间隔时间,接收者发现某一序列号消息丢失,消息重发请求发送给消息发送者,消息接收者等待超时后重新发送消息重发请求给发送者,该属性定义了这个超时时间,而且依次递增(第二次等待超时时间大于第一次)。该属性在NAKACK2中已被移除,采用xmit_interval设置统一的间隔。
discard_delivered_msgs:确定是否在接收端清除已接收的消息。默认情况下,消息接受者将接收到的消息保存起来,当use_mcast_xmit=true时,需要从非发送节点请求重传。如果我们只需要消息发送者重发消息,那么我们可以在接收端清除接收到的消息,该种情况我们需要设定此属性的值为true。
其他配置参数请参考JGroups官方文档。

UNICAST3

UNICAST3协议保证单播传输的可靠性,并保证FIFO顺序。

流控协议(UFC、MFC)

在JGroups中,流量控制采用基于信用系统(credit-based system)的实现方式。每当发送者发送了X字节数据,那么发送者剩余的信用字节将减少X字节,接收者的信用字节增加X字节。当发送者的信用字节下降到指定的阈值,此时需要接收者发送一些信用字节到发送者。如果发送者的信用字节耗尽,此时将被堵塞,直到收到了接收者发回的信用字节后方可继续发送。
JGroups支持两种类型的流控,MFC和UFC。MFC是指Multicast Flow Control,用于控制多播数据流量,UFC是指Unicast Flow Control,用于控制单播数据流量。

分裂协议(FRAG2)

当一个消息的大小大于某一确定的值时,分裂协议将消息分裂成多个小消息,然后进行发送;而在接收端,同样分裂协议将分裂的消息进行重组。不管多播还是单播发送消息,分裂协议都可以起作用。

注:

你可能感兴趣的:(JGroups协议初探)