面向分布式应用的分布式协调服务
一致性协调 CAPConsistency:一致性(每次读操作都能保证返回的是最新数据)Availability:可用性(任何一个没有发生故障的节点,会在合理的时间内返回一个正常的结果)Partition tolerance:分区容错(当节点间出现网络分区,照样可以提供满足一致性和可用性的服务)
2PC (Two-Phase Commit)备注:因为P是必须的,因此往往选择就在CP或者AP中
二阶段提交算法
阶段一:提交事务请求阶段二:执行事务提交 示意
协调者 参与者
QUERY TO COMMIT
-------------------------------->
VOTE YES/NO prepare*/abort*
<-------------------------------
commit*/abort* COMMIT/ROLLBACK
-------------------------------->
ACKNOWLEDGMENT commit*/abort*
<--------------------------------
end
3PC (Three-Phase Commit)缺点:2PC的缺点也很致命:同步阻塞,单点问题,数据不一致,太过保守
三阶段提交算法
阶段一:CanCommit阶段二:PreCommit阶段三:doCommit
协调者 参与者
CanCommit
-------------------------------->
VOTE YES/NO uncertain
<-------------------------------
Commit authorized PreCommit
-------------------------------->
ACK prepared to commit
<--------------------------------
Finaliazing commit DoCommit
-------------------------------->
haveCommitted commited
<--------------------------------
end
Paxos 算法 Basic Paxos引入超时机制。同时在协调者和参与者中都引入超时机制。
在第一阶段和第二阶段中插入一个准备阶段。保证了在最后提交阶段之前各参与节点的状态是一致的。
提议者(Proposer):代表的是接入和协调功能,收到客户端请求后,发起二阶段提交,进行共识协商;接受者(Acceptor):代表投票协商和存储数据,对提议的值进行投票,并接受达成共识的值,存储保存;学习者(Learner):代表存储数据,不参与共识协商,只接受达成共识的值,存储保存。 过程
阶段一:
(a) Proposer选择一个提案编号N,然后向半数以上的Acceptor发送编号为N的Prepare请求。(b) 如果一个Acceptor收到一个编号为N的Prepare请求,且N大于该Acceptor已经响应过的所有Prepare请求的编号,那么它就会将它已经接受过的编号最大的提案(如果有的话)作为响应反馈给Proposer,同时该Acceptor承诺不再接受任何编号小于N的提案。 阶段二:
(a) 如果Proposer收到半数以上Acceptor对其发出的编号为N的Prepare请求的响应,那么它就会发送一个针对[N,V]提案的Accept请求给半数以上的Acceptor。注意:V就是收到的响应中编号最大的提案的value,如果响应中不包含任何提案,那么V就由Proposer自己决定。(b) 如果Acceptor收到一个针对编号为N的提案的Accept请求,只要该Acceptor没有对编号大于N的Prepare请求做出过响应,它就接受该提案。 实际应用
- database replication, log replication等, 如bdb的数据复制就是使用paxos兼容的算法。Paxos最大的用途就是保持多个节点数据的一致性。naming service, 通过Paxos算法来管理所有的naming服务,则可保证high available分配可用的service给client。象ZooKeeper还提供watch功能,即watch的对象发生了改变会自动发notification, 这样所有的client就可以使用一致的,高可用的接口。config配置管理
- 同步时间所有节点的时间,并关闭防火墙至少需要3台主机进行搭建配置集群server
保证主从节点的状态同步
在Paxos算法基础上的扩展;支持崩溃恢复;ZK使用单一主进程Leader处理所有事务请求;Leader选举 服务器启动时期的 Leader 选举
- 每个Server发出一个投票投给自己。由于是初始情况,Server1和Server2都会将自己作为Leader服务器来进行投票,每次投票会包含所推举的服务器的myid和ZXID,使用(myid, ZXID)来表示,此时Server1的投票为(1, 0),Server2的投票为(2, 0),然后各自将这个投票发给集群中其他机器。接受来自各个服务器的投票。集群的每个服务器收到投票后,首先判断该投票的有效性,如检查是否是本轮投票、是否来自LOOKING状态的服务器。处理投票。针对每一个投票,服务器都需要将别人的投票和自己的投票进行PK,优先检查ZXID,在检查myid。比较大的服务器优先作为Leader。统计投票。每次投票后,服务器都会统计投票信息,判断是否已经有过半机器接受到相同的投票信息,对于Server1、Server2而言,都统计出集群中已经有两台机器接受了(2, 0)的投票信息,此时便认为已经选出了Leader。改变服务器状态。一旦确定了Leader,每个服务器就会更新自己的状态,如果是Follower,那么就变更为FOLLOWING,如果是Leader,就变更为LEADING。
- 变更状态。Leader挂后,余下的非Observer服务器都会将自己的服务器状态变更为LOOKING,然后开始进入Leader选举流程。每个Server会发出一个投票。在这个过程中,需要生成投票信息(myid,ZXID)每个服务器上的ZXID可能不同。接收来自各个服务器的投票。与启动时过程相同。处理投票。与启动时过程相同,此时,Server1将会成为Leader。统计投票。与启动时过程相同。改变服务器的状态。与启动时过程相同。
统一命名服务:在分布式环境下,经常需要对应用/服务进行统一命名,便于识别;统一配置管理:配置文件同步、管理;统一集群管理:可以实现实时监控节点状态变化,服务将节点信息写入;服务器动态上下线:软负载均衡:记录每台服务器的访问数; 节点类型
- 持久化目录节点:客户端与 Zookeeper 断开连接后,该节点依旧存在。持久化顺序编号目录节点:客户端与 Zookeeper 断开连接后,该节点依旧存在,只是 Zookeeper 给该节点名称进行顺序编号临时目录节点:客户端与 Zookeeper 断开连接后,该节点被删除临时顺序编号目录节点:客户端与 Zookeeper 断开连接后,该节点被删除,只是 Zookeeper 给该节点名称进行顺序编号。
持久化目录节点:用于长连接;如用zk来管理数据库创建持久化节点可以避免频繁与数据库的交互,而带来的资源消耗;持久化节点也有弊端:不能及时的获取最新的资源;持久化顺序编号目录节点:使用场景少,用于复杂业务中有序的获取资源;临时目录节点:常见的dubbo架构中service服务的注册,分布式锁(原理后面文章会讲解【–创建相同节点时返回false】)临时顺序编号目录节点:用于分布式锁实现复杂业务有序处理; Stat结构体
czxid: 创建节点的事务 zxid(每次修改 ZooKeeper 状态都会收到一个 zxid 形式的时间戳,也就是 ZooKeepe r事务 ID。事务 ID 是 ZooKeeper 中所有修改总的次序。每个修改都有唯一的 zxid,若 zxid1 小于 zxid2,那么 zxid1 在 zxid2 之前发生。)ctime: znode 被创建的毫秒数(从 1970 年开始)mzxid: znode 最后更新的事务 zxidmtime: znode 最后修改的毫秒数(从 1970 年开始)pZxid: znode 最后更新的子节点 zxidcversion : znode 子节点变化号,znode 子节点修改次数dataversion: znode 数据变化号aclVersion: znode 访问控制列表的变化号ephemeralOwner: 如果是临时节点,这个是 znode 拥有者的 session id。如果不是临时节点则是 0。dataLength: znode 的数据长度numChildren: znode 子节点数量 监听器
监听节点数据的变化监听子节点增减的变化



