Kafka中的coordinator

本文介绍了Kafka在0.9版本后如何通过中心Coordinator实现Rebalance,避免Zookeeper的问题。详细讨论了触发Rebalance的五种条件,以及Consumer在Rebalance过程中的角色,包括启动时找寻Coordinator、发送HeartbeatRequest、处理非法Generation错误码等步骤。同时,概述了Consumer的状态机和故障检测机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在0.9以前的client api中,consumer是要依赖Zookeeper的。因为同一个consumer group中的所有consumer需要进行协同,进行下面所讲的rebalance。

但是因为zookeeper的“herd effect”与“split brain”,导致一个group里面,不同的consumer拥有了同一个partition,进而会引起消息的消费错乱。为此,在0.9中,不再用zookeeper,而是Kafka集群本身来进行consumer之间的同步。(注:herd effect任何Broker或者Consumer的增减都会触发所有的Consumer的Rebalance;split brain:每个Consumer分别单独通过Zookeeper判断哪些Broker和Consumer 宕机了,那么不同Consumer在同一时刻从Zookeeper“看”到的View就可能不一样,这是由Zookeeper的特性决定的,这就会造成不正确的Reblance尝试。

所谓rebalance,就是在某些条件下,partition要在consumer中重新分配。那哪些条件下,会触发rebalance呢? 
条件1:有新的consumer加入 
条件2:旧的consumer挂了 
条件3:coordinator挂了,集群选举出新的coordinator 
条件4:topic的partition新加 
条件5:consumer调用unsubscrible(),取消topic的订阅

如何通过中心Coordinator实现Rebalance

成功Rebalance的结果是,被订阅的所有Topic的每一个Partition将会被Consumer Group内的一个(有且仅有一个)Consumer拥有。每一个Broker将被选举为某些Consumer Group的Coordinator。某个Cosnumer Group的Coordinator负责在该Consumer Group的成员变化或者所订阅的Topic的Partititon变化时协调Rebalance操作。

Consumer

1) Consumer启动时,先向Broker列表中的任意一个Broker发送ConsumerMetadataRequest,并通过 ConsumerMetadataResponse获取它所在Group的Coordinator信息。ConsumerMetadataRequest 和ConsumerMetadataResponse的结构如下

ConsumerMetadataRequest
{
  GroupId                => String
}

ConsumerMetadataResponse
{
  ErrorCode              => int16
  Coordinator            => Broker
}

2)Consumer连接到Coordinator并发送 HeartbeatRequest,如果返回的HeartbeatResponse没有任何错误码,Consumer继续fetch数据。若其中包含 IllegalGeneration错误码,即说明Coordinator已经发起了Rebalance操作,此时Consumer停止fetch数据,commit offset,并发送JoinGroupRequest给它的Coordinator,并在JoinGroupResponse中获得它应该拥有的所有 Partition列表和它所属的Group的新的Generation ID。此时Rebalance完成,Consumer开始fetch数据。相应Request和Response结构如下

HeartbeatRequest
{
  GroupId                => String
  GroupGenerationId      => int32
  ConsumerId             => String
}

HeartbeatResponse
{
  ErrorCode              => int16
}

JoinGroupRequest
{
  GroupId                     => String
  SessionTimeout              => int32
  Topics                      => [String]
  ConsumerId                  => String
  PartitionAssignmentStrategy => String
}

JoinGroupResponse
{
  ErrorCode              => int16
  GroupGenerationId      => int32
  ConsumerId             => String
  PartitionsToOwn        => [TopicName [Partition]]
}
TopicName => String
Partition => int32

Consumer状态机

Down:Consumer停止工作

Start up & discover coordinator:Consumer检测其所在Group的Coordinator。一旦它检测到Coordinator,即向其发送JoinGroupRequest。

Part of a group:该状态下,Consumer已经是该Group的成员,并周期性发送HeartbeatRequest。如 HeartbeatResponse包含IllegalGeneration错误码,则转换到Stopped Consumption状态。若连接丢失,HeartbeatResponse包含NotCoordinatorForGroup错误码,则转换到 Rediscover coordinator状态。

Rediscover coordinator:该状态下,Consumer不停止消费而是尝试通过发送ConsumerMetadataRequest来探测新的Coordinator,并且等待直到获得无错误码的响应。

Stopped consumption:该状态下,Consumer停止消费并提交offset,直到它再次加入Group。

故障检测机制

Consumer成功加入Group后,Consumer和相应的Coordinator同时开始故障探测程序。Consumer向 Coordinator发起周期性的Heartbeat(HeartbeatRequest)并等待响应,该周期为 session.timeout.ms/heartbeat.frequency。若Consumer在session.timeout.ms内未收到 HeartbeatResponse,或者发现相应的Socket channel断开,它即认为Coordinator已宕机并启动Coordinator探测程序。若Coordinator在 session.timeout.ms内没有收到一次HeartbeatRequest,则它将该Consumer标记为宕机状态并为其所在Group触发一次Rebalance操作。

Coordinator Failover过程中,Consumer可能会在新的Coordinator完成Failover过程之前或之后发现新的Coordinator并向其发送HeatbeatRequest。对于后者,新的Cooodinator可能拒绝该请求,致使该Consumer重新探测Coordinator并发起新的连接请求。如果该Consumer向新的Coordinator发送连接请求太晚,新的Coordinator可能已经在此之前将其标记为宕机状态而将之视为新加入的Consumer并触发一次Rebalance操作。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值