Kafka GroupCoordinator机制(十二):GroupCoordinator之GroupState之DelayedJoin分析

消费者组的状态切换成prepareRebalance会创建一个DelayedJoin的对象,添加到GroupCoordinator.joinPurgatory中管理,它是一种延迟操作,主要功能是等待消费者组中所有消费者发送joinGroupRequest申请加入。每当处理完新接收到的joinGroupRequest时,都会检测相关的delayedJoin是否能够完成,经过一段时间,delayedJoin也会执行到期。
DelayJoin各个字段的含义:

private[coordinator] class DelayedJoin(
                                            // GroupCoordinator对象,DelayedJoin中方法的实现方法是调用GroupCoordinator中对应的方法
                                            coordinator: GroupCoordinator,
                                            // DelayedJoin对应的GroupMetadata对象
                                            group: GroupMetadata,
                                            // delayedJoin的到时时长,GroupMetadata中所有member设置的超时时间最大值。
                                            sessionTimeout: Long)
  extends DelayedOperation(sessionTimeout) {
        override def tryComplete(): Boolean = coordinator.tryCompleteJoin(group, forceComplete)
        override def onExpiration() = coordinator.onExpireJoin()
        override def onComplete() = coordinator.onCompleteJoin(group)
  }

tryCompleteJoin方法通过判断groupMetadata中已知member是否已重新申请加入来决定delayedJoin是否符合执行条件

  def tryCompleteJoin(group: GroupMetadata, forceComplete: () => Boolean) = {
    group synchronized {
        // 判断已知memeber是否已经申请加入
      if (group.notYetRejoinedMembers.isEmpty)
        forceComplete()
      else false
    }
  }  
  // awaitingJoinCallback判断member是否已经重新加入
  def notYetRejoinedMembers = members.values.filter(_.awaitingJoinCallback == null).toList
  

当已知member都已经申请重新加入或delayedJoin到期时,会执行onComplete方法。首先把未重新申请加入的已知member删除,如果GroupMetadta中不再包含任何member,则将consumer Group转换成dead状态,删除对应的GroupMetadata对象并向__CONSUMER_OFFSET中对应的分区写入删除标志,之后更新generationID,调用awaitingSyncCallback回调函数,向对应的Consumer发送JoinGroupResponse。

  def onCompleteJoin(group: GroupMetadata) {
    group synchronized {
        //获取未重新申请加入的已知member集合
      val failedMembers = group.notYetRejoinedMembers
      if (group.isEmpty || !failedMembers.isEmpty) {
        failedMembers.foreach { failedMember =>
        // 移除未加入的已知member
          group.remove(failedMember.memberId)
          // TODO: cut the socket connection to the client
        }

        // TODO KAFKA-2720: only remove group in the background thread
        // 如果GroupMetadata中已经没有member,就把GroupMetadata切换成dead状态
        if (group.isEmpty) {
          group.transitionTo(Dead)
          // 移除GroupMetadata对象,并在对应__CONSUMER_OFFSETS的分区中添加删除标志
          groupManager.removeGroup(group)
          info("Group %s generation %s is dead and removed".format(group.groupId, group.generationId))
        }
      }
      if (!group.is(Dead)) {
          // 递增genrationID,并且决定用的分区分配策略
        group.initNextGeneration()
        info("Stabilized group %s generation %s".format(group.groupId, group.generationId))

        // trigger the awaiting join group response callback for all the members after rebalancing
        // 向GroupMetadata中所有的member发送JoinGroupResponse
        for (member <- group.allMemberMetadata) {
          assert(member.awaitingJoinCallback != null)
          val joinResult = JoinGroupResult(
          // 发送给leader消费者和follower消费者的JoinGroupResponse不同
            members=if (member.memberId == group.leaderId) { group.currentMemberMetadata } else { Map.empty },
            memberId=member.memberId,
            generationId=group.generationId,
            subProtocol=group.protocol,
            leaderId=group.leaderId,
            errorCode=Errors.NONE.code)
          // 调用回调函数,将响应放在RequestChannel中
          member.awaitingJoinCallback(joinResult)
          member.awaitingJoinCallback = null
          // 心跳
          completeAndScheduleNextHeartbeatExpiration(group, member)
        }
      }
    }
  }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值