leader选举
zookeeper在集群启动或原leader宕机后会进行leader选举,选举过程大致如下:
- 每个实例通过发送“实例id+最大事务id”的消息来协调选举,例如实例1初始事务id为0,那么将首先选举自己,即向其他所有实例发送消息:(1,0)
- 一个实例收到选举消息后和自己的选举消息进行对比,首先判断事物id,以大的为准;其次判断实例id,也是以大的为准。如果收到了比自己大的,则更新自己的投票,并将更新后的选举消息发送出去。
- 每个实例收到投票后进行统计,如果发现投票某个实例的数量大于集群总数的1/2,则认为它是leader。
- 产生leader后,若实例自己是leader则进入leader模式;否则进入follower或observer模式。
为什么选取事务id大的实例为leader?
为了保证集群事务处于最新状态。zookeeper要求非leader必须和leader状态一致,因此,选取事务id大的作为leader可以保证集群事务处于最新状态。
事务流程
leader作为zookeeper的事务唯一处理者,follower或observer接收到事务请求都将转发给leader进行处理。zookeeper事务处理以责任链的形式进行,过程大致分为sync、vote、commit三个阶段。为了保证事务处理的顺序性,每个阶段都有对应的事务缓存队列,事务首先放入缓存队列,由专门的处理器从队列中获取事务对象处理。
- sync:leader接收到事务请求后首先进入sync流程。类似于数据库事务,该流程中首先写事务日志,成功后进入vote阶段。
- vote:对于事务请求,zookeeper要进行投票,超过集群半数实例通过后才能执行。投票就是将事务消息发送给所有folloer,follower收到投票请求后同样先写事务日志,然后返回leader确认消息ack。
- commit:leader收到超过半数ack后就进行事务执行,也就是写具体的内存数据库。数据更新完成后给所有follower发送commit消息,follower收到消息后同样更新数据并返回ack。这里对于observer进行了特殊处理,由于observer没有投票权,所有不能简单发送commit消息,需要发送包含数据的inform消息。