kafka消费者组与重平衡

 消费者组

         消费者组(Consumer Group)是kafka提供的可扩展且具有容错性的消费者机制。其特性如下。

        1.一个消费者组包含多个消费者,它们共享一个gruop id,但一个消费者只能在一个消费者组中。

        2.消费者组订阅的topic下的一个分区只能被组中一个消费者消费(设置消费者时最好分区数=消费者数)。

        3.不同消费者组中的消费者可以消费同一个topic下的同一个分区。

        通过以上特性,当所有消费者都在一个消费者组中kafka实现了点对点模型。当所有消费者在多个组中kafka实现发布/订阅模型。

重平衡

        重平衡(Rebalance)是消费者组中重要机制之一,其目的就是分配消费者组中消费者订阅topic中的每个分区。例如现在有10个分区,5个消费者,在为消费者分配分区的过程就是重平衡。在重平衡进行期间,kafka不能处理任何请求。使用kafka客户端时可通过ConsumerConfig.PARTITION_ASSIGNMENT_STRATEGY_CONFIG设置重平衡策略。

重平衡触发时机及避免

1.消费者组内成员变更:

        消费者组内成员新增或删减时会触发重平衡,新增与正常删减成员无法避免重平衡,但是可以避免意外删减成员造成的重平衡。

        例如kafka间通过心跳判断消费者是否在线,可以修改心跳超时时间及心跳时间降低成员变更误判。设置session.timeout.ms = 6s(心跳超时时间),heartbeat.interval.ms = 2s(心跳时间)使其最少进行三轮心跳请求。

        或者调整max.poll.interval.ms(两次poll的时间间隔),避免业务逻辑处理时间过长导致重平衡。

2.topic内分区数变更:

        分区数变更一般为主动操作导致,无法避免重平衡,可在业务流量低时进行操作。

3.使用正则订阅主题:

        新增满足正则条件的主题时会触发重平衡,避免方式只能不使用正则订阅。

重平衡策略

        kafka提供三种重平衡策略,位于org.apache.kafka.clients.consumer包下,具体分配策略可参考kafka2.8.0 consumer api,点击链接搜索对应策略查看。

1.RangeAssignor:

        根据每个主题的分区分配,如果主题的分区不能平均分配给组内每个消费者,那么对该主题,某些消费者会被分配到额外的分区。

        例如有两个消费者C0和C1,两个主题t0和 t1,每个主题有3个分区,构成t0p0,t0p1, t0p2,t1p0,t1p1,t1p2。最终分配结果会是

        C0: [t0p0, t0p1, t1p0, t1p1] 

        C1: [t0p2, t1p2]

2.RoundRobinAssignor:

        根据全部主题的分区分配,循环分配所有可用分区和所有可用消费者,理想情况下会平均分配所有分区。

        例如有两个消费者C0和C1,两个主题t0和t1,每个主题有3个分区,构成t0p0,t0p1,t0p2, t1p0,t1p1,和t1p2。其分配结果为

        C0: [t0p0, t0p2, t1p1]

        C1: [t0p1, t1p0, t1p2]

        但消费者实例之间的订阅不同时会造成分配不均情况,例如现在有 3 个消费者C0、C1、C2和 3 个主题t0、t1、t2,分别有 1、2 、3 个分区。构成t0p0、t1p0、t1p1、t2p0、t2p1、t2p2。 C0订阅t0。 C1订阅t0, t1。C2订阅了t0, t1, t2。

        C0: [t0p0]

        C1: [t1p0]

        C2: [t1p1, t2p0, t2p1, t2p2]

3.StickyAssignor:

        最复杂的分配策略,主要是为了让目前的分配尽可能保持不变,只挪动尽可能少的分区来实现重平衡并达到均匀分配的目的。

        假设有 3 个消费者C0, C1, C2, 4 个主题t0, t1, t2, t3, , 每个主题有 2 个分区,从而产生分区t0p0, t0p1, t1p0, t1p1, t2p0, t2p1, t3p0, t3p1。每个消费者都订阅了所有三个主题

        初始分配为:

        C0: [t0p0, t1p1, t3p0]

        C1: [t0p1, t2p0, t3p1]

        C2: [t1p0, t2p1]

        当C1宕机后,使用RoundRobinAssignor分配策略则会变成

        C0: [t0p0, t1p0, t2p0, t3p0]

        C2: [t0p1, t1p1, t2p1, t3p1]

        使用StickyAssignor分配策略,则会保留原C0,C2分区,变更为

        C0: [t0p0, t1p1, t3p0, t2p0]

        C2: [t1p0, t2p1, t0p1, t3p1]

重平衡流程

        重平衡主要依靠消费者端的心跳线程与coordinator(协调者)实现,其中心跳线程负责判断消费者实例是否意外宕机以及处理重平衡通知,coordinator负责重平衡分配。        

        例如消费者组新加入成员时,它会向coordinator发送 JoinGroup 请求。在该请求中coordinator会收集组内成员订阅的信息,收集完成后coordinator会从这些成员中选出一个消费者组的领导者,通过领导者制定分配方案。领导者方案制定好后向coordinator发送SyncGroup请求,将制定好的方案发送给coordinator,通过coordinator将方案发送给各消费者。

        消费者组内成员主动离开或意外宕机时与新加入成员流程类似,当成员离开时发送LeaveGroup请求coordinator收到后同样会收集组内成员信息选举领导者进行分配。消费者组内成员意外宕机时可通过心跳线程发现进行处理。

你可能感兴趣的:(kafka,kafka)