Kafka中的coordinator

来源:互联网 发布:打雷可以看网络电视 编辑:程序博客网 时间:2024/05/18 03:55

在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 => StringPartition => 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操作。


0 0
原创粉丝点击