Zookeeper的基本操作

  • 四种节点类型
  •  PERSIST【永久节点,会被永久化到磁盘当中,ZooKeeper重启之后这些节点还会继续存在】
  • PERSIST_SEQUENTIAL【顺序节点,例如:如果有一个节点,我们将它设置成该类型,那么多个客户端可以同时重建相同的节点,但是他会根据先后顺序会在后边加一个序列号,比如第一个创建的是/a/b-00001,第二个就是/a/b-00002】
  • EPHEMERAL【机器重启之后,这种类型的节点不会存在】
  • EPHEMERAL_SEQUENTIAL【与第二种类型相反,当创建了/a/b,第二个节点继续创建,就会报错,说这个节点已经存在】
  • 可注册Watch操作
  • Created event:Enabled with a call to exists【创建一个节点】
  • Deleted event:Enabled with a call to exists, getData, and getChildren【删除一个节点】
  • Changed event:Enabled with a call to exists and getData【改变某个节点的值】
  • Child event:Enabled with a call to getChildren【有些子节点被创建或者删除】
  • Watch特征
  • 客户端先得到通知再得到数据【刚开始通过event看是不存在的,后来被创建了,客户端在得到数据之前,它肯定先得到一个通知,这个节点被创建了,或者Changed event ,getData先获取到一个值,比如:1,后来这个值被改成2,再次得到2之前肯定是先得到Changed event这个事件,然后才能得到最新的值】
  • Watch被fire后即取消,不会再Watch后续【如果我们希望去监控节点的变化,那么我们就需要再次去注册,那么在fire之后,到创建之前,如果这段时间中数据有变化,我们的客户端是得不到任何的通知】

基于Zookeeper的Leader Election

抢注Leader节点——非公平模式

  1. 创建Leader父节点,如 /chroot,并将其设置为persist节点
  2. 各客户端通过在/chroot下创建Leader节点,如/chroot/leader,来竞争Leader。该节点应被设置为ephemeral
  3. 若某创建Leader节点成功,则该客户端成功竞选为Leader
  4. 若创建Leader节点失败,则竞选Leader失败,在/chroot/leader节点上注册exist的watch,一旦该节点被删除则获得通知
  5. Leader可通过删除Leader节点来放弃Leader
  6. 如果Leader宕机,由于Leader节点被设置为ephemeral,Leader节点会自行删除。而其它节点由于在Leader节点上注册了watch,故可得到通知,参与下一轮竞选,从而保证总有客户端以Leader角色工作

先到先得,后者监视前者——公平模式

  1. 创建Leader父节点,如 /chroot,并将其设置为persist节点
  2. 各客户端通过在/chroot下创建Leader节点,如/chroot/leader,来竞争Leader。该节点应被设置为ephemeral_sequential
  3. 客户端通过getChildren方法获取/chroot/下所有子节点,如果其注册的节点的id在所有子节点中最小,则当前客户
    端竞选Leader成功【
    没有被竞选称为Leader的节点都去注册id比自己小的并且最大的那个节点,换句话说我们把所有的节点按id去排序
  4. 否则,在前面一个节点上注册watch,一旦前者被删除,则它得到通知,返回步骤3(并不能直接认为自己成为新
    Leader,因为可能前面的节点只是宕机了)
  5. Leader节点可通过自行删除自己创建的节点以放弃Leader

Leader Election在Curator中的实现

LeaderLatch

  • 竞选为Leader后,不可自行放弃领导权
  • 只能通过close方法放弃领导权
  • 强烈建议增加ConnectionStateListener,当连接SUSPENDED或者LOST时视为丢失领导权
  • 可通过await方法等待成功获取领导权,并可加入timeout
  • 可通过hasLeadership方法判断是否为Leader
  • 可通过getLeader方法获取当前Leader
  • 可通过getParticipants方法获取当前竞选Leader的

LeaderSelector

  • 竞选Leader成功后回调takeLeadership方法
  • 可在takeLeadership方法中实现业务逻辑
  • 一旦takeLeadership方法返回,即视为放弃领导权
  • 可通过autoRequeue方法循环获取领导权
  • 可通过hasLeadership方法判断是否为Leader
  • 可通过getLeader方法获取当前Leader
  • 可通过getParticipants方法获取当前竞选Leader的参与方

Kafka“各自为政”Leader Election

  • “各自为政”Leader Election
  • 每个Partition的多个Replica同时竞争Leader
  • 优点:
  • 实现简单
  • 缺点:
  • Herd Effect
  • Zookeeper负载过重
  • Latency

Kafka基于Controller的Leader Election

  • 基于Controller的Leader Election
  • 整个集群中选举出一个Broker作为Controller
  • Controller为所有Topic的所有Partition指定Leader及Follower
  • 优点:
  • 极大缓解Herd Effect问题
  • 减轻Zookeeper负载
  • Controller与Leader及Follower间通过RPC通信,高效且实时
  • 缺点:
  • 引入Controller增加了复杂度
  • 需要考虑Controller的Failover