- 浏览: 484507 次
- 性别:
- 来自: 大连
文章分类
最新评论
-
龘龘龘:
TrueBrian 写道有个问题,Sample 1中,为了控制 ...
What's New on Java 7 Phaser -
龘龘龘:
楼主总结的不错。
What's New on Java 7 Phaser -
TrueBrian:
有个问题,Sample 1中,为了控制线程的启动时机,博主实际 ...
What's New on Java 7 Phaser -
liguanqun811:
不知道楼主是否对zookeeper实现的分布式锁进行过性能测试 ...
Distributed Lock -
hobitton:
mysql的get lock有版本限制,否则get lock可 ...
Distributed Lock
4 Protocol Stack
4.1 Transport protocols
Transport protocols是指协议栈中最底层的协议,它们负责发送和接收消息。JGgroups提供了以下几种transport protocols。
4.1.1 UDP
JGroups中的UDP协议使用IP multicast向集群发送消息,使用UDP datagram向单个的成员发送unicast消息。启动后会打开两个socket,分别是multicast socket和unicast socket。Channel的地址是unicast socket的地址和端口号。UDP通常用于集群中的成员分布于LAN内的情况。
如果使用UDP和PING做为协议栈的底层协议,那么JGroups会使用IP multicast发现集群中的成员,以及向集群发送发送消息。然而,如果IP multicast在子网间被禁用,那么可以设置UDP的ip_mcast属性为false,以便指定UDP使用多个unicast messages向集群发送消息,而不是使用multicast message。此外,还需要设置PING的gossip_系列属性,以便指定PING使用GossipRouter来发现集群中的其它成员。需要注意的是,对GossipRouter的依赖可能会导致single point of failure,而且系统的可伸缩性也比较差。
在启动任何成员之前,首先要启动GossipRouter(否则成员需要处理MergeView消息用于合并subgroup的状态),例如:
java org.jgroups.stack.GossipRouter -port 5555 -bindaddress localhost
UDP和PING的配置如下:
<UDP ip_mcast="false" /> <PING gossip_host="localhost" gossip_port="5555" gossip_refresh="15000" timeout="2000" num_initial_members="3"/>
4.1.2 TCP
当集群中的成员分布于WAN时(路由器会丢弃IP multicast报文),TCP可能是唯一可用的传输协议。当使用TCP作为传输协议是,可用的发现协议有:
- PING with GossipRouter: 跟4.1.1中介绍的一样,p_mcast属性必须设置成false,GossipRouter 也必须先于集群中的成员启动。
- TCPPING: 从特定已知的成员处得到集群中其它成员的信息。
- TCPGOSSIP: 除了允许多个GossipRouters 之外,TCPGOSSIP 跟PING相同。
以下是个使用TCP和TCPPING的例子:
<TCP start_port="7800" /> + <TCPPING initial_hosts="HostA[7800],HostB[7800]" port_range="5" timeout="3000" num_initial_members="3" />
使用TCPPING的优点是不需要额外GossipRouters,而是从集群的成员中选择那些已知的成员,例如以上例子中的HostA[7800]和 HostB[7800],并从这些成员处得到其它成员的信息。TCP协议的start_port="7800"属性指定了选择7800作为端口号,如果该端口号被占用,那么尝试下一个(7801)端口号,直到找到可用的端口号。TCPPING协议会尝试连接HostA和HostB,连接的端口号的范围是从 7800到7800 + port_range -1(在以上例子中是7804)。
以下是个使用TCP和TCPGOSSIP的例子:
<TCP /> <TCPGOSSIP initial_hosts="localhost[5555],localhost[5556]" gossip_refresh_rate="10000" num_initial_members="3" />
以上例子中,initial_hosts 属性用于指定GossipRouter的地址和端口号。GossipRouter需要先于集群中的成员启动。
4.2 Reliable Message
4.2.1 pbcast.NAKACK
NAKACK协议保证了向集群的所有成员发送的消息的传输可靠性,以及消息的FIFO顺序。消息传输的可靠性是指发送的消息不会丢失。此外发送者将发送的消息编号,如果接收者没有收到特定编号的消息,那么发送者会收到重新发送的请求。FIFO顺序是指接收者会以消息发送的顺序接收消息。以下是部分 NAKACK协议的属性:
- retransmit_timeout 逗号分割的一系列毫秒数。例如100,200,400,800,1600。在第一次发送重传输请求前等待100ms,第二次发送重传输请求前等待 200ms,依此类推直到等待1600ms。从这以后,每次发送重传输请求前等待100ms。
- use_mcast_xmit 当某个成员接收到P成员发送的对于消息M的重传输请求,该成员会向P重新发送消息M。考虑到集群中的其它成员也可能没有收到消息M,如果 use_mcast_xmit设置为true,那么该成员会向整个集群重新发送消息M。如果使用UDP作为传输协议,那么JGroups使用IP Multicast;如果使用TCP作为传输协议,那么会发送n-1个unicast消息(n是集群中消息的个数)。
- use_mcast_xmit_req 跟use_mcast_xmit属性类似,不同之处在于对重传输的请求消息进行组播发送。
- xmit_from_random_member 如果xmit_from_random_member设置为true,那么JGroups会从集群的成员的中随机挑选一个成员,并向这个成员发送重传输请求。这样做优点是对于进行了负载均衡,缺点是随机挑选的那个成员可能也没有收到消息,在这种情况下还需要继续发送重传输请求。需要注意的是,如果这个属性设置为true,那么discard_delivered_msgs属性必须设置为false。
- discard_delivered_msgs 如果discard_delivered_msgs设置为true,那么集群中的成员不会缓存其它成员发送的消息(因此不需要STABLE协议来对这些消息进行垃圾收集)。这意味着重传输请求只能发送给消息的最初发送者。
- max_xmit_buf_size 通常收到的消息会缓存在retransmission table中,这个属性指定了retransmission table的上限。如果retransmission table达到上限,那么旧的项目会被丢弃。需要主要的是,设置这个属性可能导致消息丢失。
4.2.2 UNICAST
UNICAST协议保证了单独的发送者和接收者之间传递的消息的传输可靠性,以及消息的FIFO顺序。在可靠的传输协议(例如TCP)之上, UNICAST协议并不是必须的。然而,UNICAST可以防止相同发送者上的并发的消息传递。除非希望如此,否则应该在协议栈中包含UNICAST协议。
以下是部分UNICAST协议的属性:
- retransmit_timeout 逗号分割的一系列毫秒数。例如100,200,400,800,1600。在第一次发送重传输请求前等待100ms,第二次发送重传输请求前等待 200ms,依此类推直到等待1600ms。从这以后,每次发送重传输请求前等待100ms。
4.3 Failure Detection
Failure detection 的目的是检测集群内的成员是否崩溃。当某个成员被怀疑崩溃时,那么会向集群中的每个成员发送SUSPECT 消息,以进行通知。需要注意的时是,Failure detection 并不负责从集群中清除崩溃的成员(实际上是由GMS协议负责),它只是负责发现可能已经崩溃的成员,并通知集群中的其它成员。
4.3.1 FD
FD协议基于心跳消息。如果在timeout指定的毫秒内没有接收到某个成员的应答,并且在尝试了max_tries 指定的次数后,那么这个成员会被标记为可疑,并将被GMS协议从集群中清除。
每个成员向其右侧的邻居(当前view的成员列表中,该成员的下一个成员。列表中最后的成员的右侧邻居是列表的第一个成员)发送带有 FdHeader.HEARTBEAT头的消息。当邻居收到这个消息后,它会应答带有FdHeader.HEARTBEAT_ACK头的消息。每当收到应答时,FD协议的last_ack属性会被更新成当前的时间,num_tries也会设置为0。如果当前时间和last_ack之差大于timeout指定的毫秒数,那么FD协议会最多尝试max_tries 指定的次数,如果仍然没有收到应答,那么这个邻居会被标记为可疑。
4.3.2 FD_SOCK
FD_SOCK协议基于一个有TCP sockets组成的环,即集群中的每个成员都通过TCP socket连接到右侧的邻居(当前view的成员列表中,该成员的下一个成员。列表中最后的成员的右侧邻居是列表的第一个成员)。当某个成员检测到它的邻居非正常地关闭了TCP socket之后,那么它会把这个邻居标记为可疑。
4.4 Miscellaneous
4.4.1 STABLE
为了响应可能的重传输请求,集群中的成员需要保存一定数量的消息直到它确定这些消息已经被集群中所有的成员成功地接收。对于某个消息M来说, message stability 意味着M已经被集群中所有的成员接收。STABLE协议周期性地(或者收到消息的字节数达到的配置的上限)向集群中的所有成员发送stable messages,这些消息中包含了特定成员收到的最大序号。当集群中的每个成员都收到了其它所有成员的stable messages后,可以计算出目前每个成员已经收到的消息的最小序号,接下来这个序号被发送到集群中每个成员,最后每个成员会从自己的 retransmission tables中删除小于这个最小序号的最小消息。需要注意的是,如果没有在协议栈中配置STABLE,那么可能会导致内存耗尽。以下是个配置STABLE 协议的例子:
<pbcast.STABLE stability_delay="1000" desired_avg_gossip="50000" max_bytes="1000000"/>
以上例子中stability_delay属性指定,在发送消息前等待1~1000毫秒,以避免所有的成员同时发送消息。 desired_avg_gossip属性指定发送stable messages的周期,单位是毫秒,如果是0,那么禁用周期检查。max_bytes指定了在发送stable message消息前,接收到的消息的最大字节数。
4.4.2 pbcast.FLUSH
4.2 Reliable Message中介绍了保证消息可靠传输的协议,但是在某些情况下,这种保证是不够的,考虑以下情况:
集群中某个成员A向集群发送消息M1,此时A的当前View是V1={A,B,C},也就是说A认为M1将发送到A(如果Channel.LOCAL选项是true)、B和C。正在此时,D也加入到集群中,那么D可能会,也可能不会收到M1。
通过在协议栈中配置FLUSH协议可以保证:
- 发送到V1的消息只会被传递到V1。所以以上例子中D不会收到M1。
- 在安装V2前,集群中所有的成员都收到相同的消息。例如一个集群V1={A,B,C}中,C发送了5个消息,A收到了C发送的这5个消息,但是B 只收到了其中前3个。如果此时C崩溃,那么FLUSH协议会保证,在安装V2={A,B} 前,B会收到所有C发送过的消息。在这种情况下,A会向B发送后两个消息。
通常,在以下两种情况下需要使用FLUSH协议:
- State transfer 当某个成员请求状态传递时,它通知其它成员停止发送消息并等待响应。接下来coordinator会将状态发送给这个成员。当该成员接收到状态后,它通知其它成员可以继续发送消息。
- View changes 在安装新的view时,所有发送到V1的消息都会被传递到V1。
FLUSH协议通常在STATE_TRANSFER、STATE_TRANSFER 或者 GMS 协议之上。此外需要注意的时,FLUSH协议必须是协议栈的最上层协议。除了JGroups自动处理FLUSH之外,JGroups也允许开发人员显式调用 Channel.startFlush()方法发起flush。在Channel.startFlush()方法返回后,在调用 Channel.stopFlush()方法之前,可以保证集群中的所有成员不能发送消息,而且Channel.startFlush()方法调用前发送的消息都会被所有成员接收。在调用了Channel.stopFlush()方法之后,集群中的所有成员可以继续发送消息。
如果将Channel.BLOCK属性设置为true(缺省是false),那么可以在flush阶段得到通知。如果采用poll方式,那么在某个成员调用Channel.startFlush()方法后,其它成员会收到EVENT.BLOCK消息,这些成员应该发送EVENT.BLOCK_OK消息进行响应。如果采用push方式,那么channel上注册的MembershipListener的block()方法会被调用。
4.4.3 MERGE2
假设由于某种原因(例如switch故障),某个集群{A,B,C,D,E},分裂为两个子集群{A,B,C} 和{D,E},A、B和C可以互相ping通,D和E可以互相ping通,但是A、B和C却ping不通D和E。在这种情况下,由于两个子集群独立工作,会导致这两个子集群的状态并不相同。当故障解除后,MERGE2协议会通知集群中的成员,这两个子集群将合并成一个。
至于如何处理状态的合并,需要应用程序自己决定,这是因为JGroups并不了解集群的状态。需要注意的是,用于合并的状态的代码应该在单独的线程中执行。一种简单的处理方式是对于原来是主子集群中的成员不做任何处理,对于其它的成员则丢弃当前状态,从合并后集群的coordinator处重新获得状态。
评论
发表评论
-
Understanding the Hash Array Mapped Trie
2012-03-30 10:36 0mark -
A Hierarchical CLH Queue Lock
2012-01-14 19:01 2152A Hierarchical CLH Queue Lock ( ... -
Inside AbstractQueuedSynchronizer (4)
2012-01-08 17:06 3528Inside AbstractQueuedSynchroniz ... -
Inside AbstractQueuedSynchronizer (3)
2012-01-07 23:37 4756Inside AbstractQueuedSynchroniz ... -
Inside AbstractQueuedSynchronizer (2)
2012-01-07 17:54 6372Inside AbstractQueuedSynchroniz ... -
Inside AbstractQueuedSynchronizer (1)
2012-01-06 11:04 7953Inside AbstractQueuedSynchroniz ... -
Code Optimization
2011-10-14 00:11 1613当前开发人员在进行编码的时候,可能很少关注纯粹代码级别的优化了 ... -
Distributed Lock
2011-08-02 22:02 92171 Overview 在分布式系统中,通常会 ... -
What's New on Java 7 Phaser
2011-07-29 10:15 82871 Overview Java 7的并 ... -
Sequantial Lock in Java
2011-06-07 17:00 22251 Overview Linux内核中常见的同步机 ... -
Feature or issue?
2011-04-26 22:23 121以下代码中,为何CglibTest.intercept ... -
Bloom Filter
2010-10-19 00:41 50811 Overview Bloom filt ... -
Inside java.lang.Enum
2010-08-04 15:40 64831 Introduction to enum J ... -
Open Addressing
2010-07-07 17:59 34821 Overview Open addressi ... -
JLine
2010-06-17 09:11 11015Overview JLine 是一个用来处理控 ... -
ID Generator
2010-06-14 14:45 1685关于ID Generator,想 ... -
inotify-java
2009-07-22 22:58 83151 Overview 最近公 ... -
Perf4J
2009-06-11 23:13 84941 Overview Perf4j是一个用于计算 ... -
Progress Estimator
2009-02-22 19:37 1541Jakarta Commons Cookbook这本书 ... -
jManage
2008-12-22 00:40 39591 Overview 由于项目需要, 笔者开发了一个 ...
相关推荐
JavaEE源代码 jgroups-2.2.8JavaEE源代码 jgroups-2.2.8JavaEE源代码 jgroups-2.2.8JavaEE源代码 jgroups-2.2.8JavaEE源代码 jgroups-2.2.8JavaEE源代码 jgroups-2.2.8JavaEE源代码 jgroups-2.2.8JavaEE源代码 ...
在Ehcache通过Jgroups进行集群配置时,首先需要理解Jgroups的配置文件——`jgroups.xml`。这个文件定义了集群中节点如何相互发现、通信以及故障检测的规则。配置文件中的关键元素包括: 1. **Transport**: 定义了...
- `log4j.jar`(可选):日志库,JGroups也可以使用JDK自带的日志框架。 - 多种XML配置文件,例如: - `mping.xml`:基于TCP的堆栈,支持动态发现。 - `sfc.xml`:基于UDP(使用IP组播)的堆栈,支持简单流控制。 ...
JGroups集群技术概述 JGroups是一个用于建立可靠的组播通信的工具包,它提供了灵活的、可定制的协议栈,以满足不同的需求。JGroups支持多种传输协议,包括UDP、TCP和JMS等。在JGroups中,消息传输可以保证可靠性,...
jgroups-raft 项目是 JGroups 框架对 Raft 的实现。Maven:<groupId>org.jgroups <artifactId>jgroups-raft <version>0.2</version>Raft 是一个容易理解的共识算法。在容错和性能方面它相当于 Paxos(Google 的一致...
jgroups-2.2.7.jar jgroups-2.2.7.jar
jgroups.part1
《深入解析JGroups开源框架:基于belaban-JGroups-19d7183源代码》 JGroups是一个用于构建高可用性集群的Java框架,它提供了可靠的消息传递、组成员管理和故障检测等功能,广泛应用于分布式系统中。本文将基于bela...
此文档主要针对JGroups 2.X版本的官方帮助文档进行详细解读,旨在帮助开发者深入理解并有效地利用JGroups。 一、JGroups简介 JGroups的核心目标是确保在分布式环境中数据的一致性。它提供了一套完整的工具,用于...
2)组成员加入和离开组 3)成员关系的自动侦测并通知成员的加入,离开和丢失(原文是crashed,大意就是说没有通知的离开吧) 4)侦测并删除丢失的成员 5)发送和接收成员到组的消息(点到多点) 6)发送和接收成员...
《JGroups:构建高效可靠的组通信系统》 JGroups是一个用Java编程语言编写的开源库,专注于实现基于IP组播的高效、可配置的组通信协议栈。它为分布式系统提供了一种健壮且灵活的方式来实现节点间的通信,是构建大...
4. acks 有延时:如果 B 发送的 ACK 消息 5,8,13,52,62,83 和 101 到 A 有 1 秒的过程中(及最小时间为 500ms),那么也许我们会有效地只发送 ACK(52)和 ACK(101)至 A,并删除其他的 ACK 在接收端,ACK ...
- `log4j.jar`(可选):commons-logging也可以使用JDK自带的日志记录。 此外,目录还包含多种XML配置文件,例如`mping.xml`,基于TCP的稳定网络环境下的配置。 ##### 测试与调试 完成安装后,应进行基本的测试来...
JGroups - A Framework for Group Communication in Java ======================================================== March 3, 1998 Bela Ban 4114 Upson Hall Cornell University Ithaca, NY 14853 bba@...
JGroups是一个开源的纯java编写的可靠的群组通讯工具。其是一个可靠的组播通讯工具集(需要说明的是,这并不是说必须要使用IP Multicast,JGroups也可以使用TCP来实现)。其工作模式基于IP多播,但可以在可靠性和群组...
4. **故障恢复**:当节点故障后,能够恢复其状态,保持集群的连续服务。 5. **一致性算法**:如View Agreement Protocol (VAP)和Total Order Broadcast (TOB),保证数据的一致性。 6. **安全特性**:支持加密和身份...
4. 高级特性: JGROUPS还支持其他高级特性,如故障检测、成员关系管理、负载均衡和复制一致性。这些特性通过不同的协议实现,使得JGROUPS成为构建分布式系统的强大工具。 通过深入理解JGROUPS的消息发送、处理和...
jgroups.part3