zookeeper探索(3):选举过程

2016-4-15 sunsmile zookeeper

使用zookeeper实现leader选举过程的一种简单方式是在创建代表参选人的客户端znode节点的时候指定SEQUENCE|EPHEMERAL标签。首先创建一个“/election”节点,然后每个客户端在此节点之下创建代表自己的znode节点,“/election/guid-n_”并同时指定SEQUENCE|EPHEMERAL这两个标签。根据SEQUENCE标签,zookeeper会自动将序号最大的znode节点放在“/election”子节点队列的最后面。序号最小的那个znode节点对应的客户端就是leader。

至此,选举过程并不完整。选举好leader之后,仍然需要监视这个leader是否失效。如果当前的leader失效,需要选举出新的leader来接替此前者的工作。一种比较简单的解决方式就是所有的客户端都监听这个需要最小的znode节点,并且检测如果最小的节点失效(对应的znode节点从/election/子节点列表中消失,因为znode节点是EPHEMERAL节点),那么所有其他进程都会判断是否自己为新的leader。但这样的处理方式会导致一个群体效应。由于当前的leader实现,所有其他客户端都会接收到通知,并且在“/election”节点执行getChildren操作,来获取“/election”节点的子节点列表。如果客户端数量比较大,这会导致zookeeper服务器会执行大量的重复操作。为了避免这种情况发生,每个节点都设置为监听前一个节点是否失效则更为高效。当一个客户端接收到znode失效的通知之后,如果没有更小序号的节点,那么直接将自己变为leader。这样就避免了所有节点监听同一个节点导致的群体效应问题。

操作过程如下:
创建“/election”节点,对于想要成为leader的客户端,
1. 在“/election”节点中创建带有SEQUENCE和EPHEMERAL标签的子节点z,即"/election/guid-n_";
2. 定义集合C为“/election”节点的子节点集合,i为节点z的序号;
3. 监听“/election/guid-n_i”的变化,j为最大序号,j<i且n_i是集合C中的一个元素;

接收到znode节点减少的通知后
1. 定义集合C为“/election”节点的新子节点集合;
2. 如果z为集合C中序号最小的节点,那么执行leader处理过程,即设置此节点为leader;
3. 否则,监听“/election/guid-n_j”的变化,j为最大序号,j<i且n_i是集合C中的一个元素;

发表评论:

Powered by emlog 京ICP备15044591号-1