1.简述
它是一个分布式一致性解决方案,为分布式应用提供分布式协调服务。
它开源、强大,得到了广泛的应用。Haddop,Storm都已经将zk作为核心组件,用于分布式协调。
2.集群角色
Leader,为客户端提供读写服务。Follower, 提供读服务,参与lerder选举。
Observer,只提供读服务。
LOOKING:当前Server不知道leader是谁,正在搜寻;
LEADING:当前Server即为选举出来的leader;
FOLLOWING:leader已经选举出来,当前Server与之同步。
3.功能
数据节点。ZooKeeper将所有数据存储在内存中,数据结构是一个树(ZNode Tree)。
会话。zk对外服务的默认端口是2181,客户端会与它建立长连接。
事件监听器。Watcher是zk的重要特性。用户可以在指定节点上注册一些watcher,当指定的事件触发后,用户得到通知。
4.ZAB协议
ZAB,Zookeeper Atomic Broadcast,zk原子广播。
zk并没有用Paxos算法,用的是自己的zkb。
主要思想是这样的。所有事务请求必须由leader协调。leader负责将客户端的事务请求转换为proposal,分发给所有follower,若超过半数的follower给出正确反馈,则leaser再向所有的follower发送commit消息。
4.1 zxid
ZooKeeper每一次的状态改变, 都对应着一个递增的Transaction id, 称为zxid。由于zxid的递增性质, 如果zxid1小于zxid2, 那么zxid1肯定早于zxid2发生。
对任意节点的增、删、改操作, 都会导致Zookeeper状态发生改变, 从而导致zxid的值增加。
实现中zxid是一个64位的数字,它高32位是epoch用来标识leader关系是否改变,每次一个leader被选出来,它都会有一个新的epoch,标识当前属于那个leader的统治时期。低32位用于递增计数。
5.Leader选举
通过投票来选举。投票是广播行为,投票格式为<sid,zxid>。
5.1投票变更策略
在没有leader或leader挂了之后,follower会将角色变更为looking,然后开始选举。
第一轮,大家都投自己。对于接收到的投票,采取如下whetherAccept()策略:
boolean whetherAccept(Vote vote){ if(vote.zxid>zxid) return true; if(vote.zxid==zxid&&vote.sid>sid) return true; return false; }若返回true,认可该投票并广播。其他情况都坚持自己原有的投票。
5.2 统计投票
每轮投票结束后,开始统计得票。如果一台机器收到了超过半数的相同投票,记为voteA,那么voteA.sid即为新的leader。
6.过半存活即可用
一个zk集群如果要对外提供服务,那么集群中必须要有过半的机器正常 工作且彼此之间通信正常。即“过半存活即可用”。
问:选leader时也用到了过半的思想,那么机器部署必须为奇数台么?
答:不是这样。根据leader选举策略,任意台都是可以的。
问:为什么推荐集群中的机器数为奇数个?
答:这是出于节省成本的考虑。因为“过半存活才可用”的思想,你部署 了10台,挂掉5台就不能用了。而你部署9台,也是挂掉5台就不能用了。