kafka21-消费者分区分配策略详解

目录

RangeAssignor 分区分配策略

基本原理

优缺点分析

应用场景

RoundRobin 分区分配策略

RoundRobin 策略的工作原理

RoundRobin 策略的不足和解决方案

RoundRobinAssignor 的核心源码

StickyAssignor 黏性分区分配策略

StickyAssignor 策略的工作原理

StickyAssignor 的优势

CooperativeStickyAssignor

CooperativeStickyAssignor 的工作原理

区别与优势


RangeAssignor 分区分配策略

基本原理

RangeAssignor 根据以下步骤为消费者组中的每个消费者分配分区:

  1. 排序消费者:对于每个订阅了主题的消费者,按照字典序(即消费者 ID)进行排序。

  2. 排序分区:对于主题中的每个分区,按照分区号进行排序。

  3. 分配范围:根据消费者数量和分区数量计算出一个基本分配数量 n,以及余数 m。前 m 个消费者将被分配 n+1 个分区,其余的消费者将被分配 n 个分区。

  4. 分配结果:根据计算的分配范围,将各个分区分配给消费者。

优缺点分析

优点

  • 简单直观:Range 分配策略易于理解和实现,只需简单的排序和分配。
  • 分区均衡:在单个主题的情况下,能够实现相对均衡的分区分配,避免了一些消费者空闲而另一些消费者负载过重的情况。

缺点

  • 缺乏全局视野:RangeAssignor 缺乏对整体消费者组负载的全局优化视角。在多个主题的情况下,排在前面的消费者可能会被分配更多的分区,这可能导致负载不均衡,特别是当不同主题的消息量差异较大时。
  • 消费者组动态性差:当消费者组的消费者数量发生变化时,可能需要重新分配所有分区,这会带来一定的性能开销和系统不稳定性。

应用场景

  • 适合单个主题的场景:当消费者组仅订阅了单个主题时,RangeAssignor 能够提供相对均衡的分区分配。
  • 相同消息键的优化:如果多个主题使用相同的消息键(key),那么这些消息将被分配到各自主题的同一个分区中。在这种情况下,Range 分配策略可以确保相关的消息被分配给同一个消费者,从而提高消费效率。

RoundRobin 分区分配策略

RoundRobin 轮询分区分配策略是 Kafka 消费者组中的一种经典分配策略,其核心思想是将订阅的所有分区(不考虑主题)轮流分配给每个消费者,从而提高并行处理能力。然而,RoundRobin 策略也存在一些不足之处,特别是在消费者订阅的主题不完全相同时可能出现的分配不均衡问题。

RoundRobin 策略的工作原理

RoundRobinAssignor 的实现逻辑可以简单概括如下:

  1. 消费者排序:首先按照消费者 ID 的字典序进行排序,形成一个消费者列表。

  2. 分区排序:对于订阅的所有分区,按照分区号进行排序。

  3. 轮询分配:依次将排序后的分区分配给每个消费者。消费者按顺序轮流接收分区,直到所有分区都被分配完毕。

这种策略确保了每个消费者在理论上能够平均分配分区,从而减少了空闲消费者的数量,提高了整体的并行度和吞吐量。

RoundRobin 策略的不足和解决方案

  1. 主题订阅不均衡问题

    • 问题描述:如果同一个消费者组中,每个消费者订阅的主题数量或分区数量不同,则可能导致分配不均衡。比如某些消费者订阅了更多的主题或分区,而其他消费者则订阅较少。
    • 解决方案:可以通过更智能的分配策略来解决这种不均衡。例如,使用 StickyAssignor 策略,它能够尽量保持消费者与分区之间的稳定关系,在消费者组发生变动时减少不必要的分区重新分配。
  2. Rebalance 后的分配失衡问题

    • 问题描述:如果在消费者组中的某个消费者宕机或加入,RoundRobinAssignor 策略会导致所有分区重新分配,可能导致分配不均衡。
    • 解决方案:除了 StickyAssignor 外,还可以考虑其他支持更精细控制的分配策略,如 CooperativeSticky 策略,它在 Kafka 2.4 版本中引入,结合了 Sticky 和 RoundRobin 的优点,能够更好地处理消费者组动态变化时的分配问题。

RoundRobinAssignor 的核心源码

public class RoundRobinAssignor extends AbstractPartitionAssignor {
    @Override
    public Map<String, List<TopicPartition>> assign(Map<String, Integer> partitionsPerTopic,
                                                    Map<String, Subscription> subscriptions) {
        Map<String, List<TopicPartition>> assignment = new HashMap<>();
        List<MemberInfo> memberInfoList = new ArrayList<>();
        for (Map.Entry<String, Subscription> memberSubscription : subscriptions.entrySet()) {
            assignment.put(memberSubscription.getKey(), new ArrayList<>());
            memberInfoList.add(new MemberInfo(memberSubscription.getKey(),
                                              memberSubscription.getValue().groupInstanceId()));
        }
        CircularIterator<MemberInfo> assigner = new CircularIterator<>(Utils.sorted(memberInfoList));
        for (TopicPartition partition : allPartitionsSorted(partitionsPerTopic, subscriptions)) {
            final String topic = partition.topic();
            while (!subscriptions.get(assigner.peek().memberId).topics().contains(topic))
                assigner.next();
            assignment.get(assigner.next().memberId).add(partition);
        }
        return assignment;
    }
}

StickyAssignor 黏性分区分配策略

StickyAssignor 策略的工作原理

StickyAssignor 策略基于以下几个核心概念:

  1. 黏性分配:在正常情况下,StickyAssignor 会尽量保持分区与消费者的稳定关系。也就是说,如果某个消费者在一个分区上消费,那么尽量在 Rebalance 时将这个分区继续分配给同一个消费者,避免频繁的重新分配,从而减少系统的不稳定性和性能开销。

  2. 处理 Rebalance

    • 消费者离线:当某个消费者离线(比如宕机)时,StickyAssignor 会将该消费者负责的分区尽量分配给其他在线的消费者,但会尽量保持其他消费者原有的分区不变。
    • 新消费者加入:当新的消费者加入消费者组时,StickyAssignor 会尽量将新增的分区分配给这些新消费者,同时尽量保持现有消费者的分区不变。
  3. 优化分配策略:StickyAssignor 在分配分区时,除了保持黏性外,还会优化分配的平衡性,避免某些消费者过载或空闲的情况,尽可能实现整体的负载均衡。

StickyAssignor 的优势

  1. 减少分区重新分配:相比于 RoundRobinAssignor,在 Rebalance 过程中尽可能减少分区的重新分配,从而减少了整个系统的不稳定性和性能开销。

  2. 分配均衡性:StickyAssignor 在保持黏性的基础上,还会尽量保持分区的均衡分配,避免某些消费者处理过多或过少的分区。

  3. 适应动态变化:对于消费者组中消费者的动态变化(加入或离线),StickyAssignor 能够快速响应并进行合适的分区重新分配,保证消费者组的稳定性和高效性。

CooperativeStickyAssignor

CooperativeStickyAssignor 的工作原理

CooperativeStickyAssignor 与 StickyAssignor 类似,都是为了在 Kafka 消费者组发生 Rebalance(重新分配分区)时尽可能保持消费者的分区分配稳定,以减少因 Rebalance 导致的全局停顿和性能下降。

  1. 渐进式 Rebalance:CooperativeStickyAssignor 使用 COOPERATIVE 协议,这意味着它在处理 Rebalance 时采取渐进式的分区重新分配策略。具体来说,它将一个大的全局 Rebalance 过程拆分为两个小规模的 Rebalance 过程:

    • 第一次 Rebalance:在第一次 Rebalance 过程中,消费者仍然持有它们当前分配的分区,但可能会收到新的分区分配。

    • 第二次 Rebalance:在第二次 Rebalance 过程中,消费者放弃被撤销的分区,并接收最终的新分配。

    这种分阶段的 Rebalance 过程使得消费者组在 Rebalance 期间可以维持更高的稳定性和可用性,避免了全局的 Stop The World。

  2. 保持黏性:与 StickyAssignor 类似,CooperativeStickyAssignor 也会尽量保持消费者与分区的黏性,即尽量让每个消费者在 Rebalance 后继续消费它之前所处理的分区,从而减少不必要的重新分配。

区别与优势

CooperativeStickyAssignor 相对于传统的 EAGER 协议(如 StickyAssignor)有以下优势和区别:

  • 避免全局 Stop The World:传统的 EAGER 协议要求在 Rebalance 期间所有消费者放弃当前的分区,导致全局的停顿。而 CooperativeStickyAssignor 使用 COOPERATIVE 协议,通过渐进式的 Rebalance 过程避免了这种全局停顿,提高了系统的稳定性和可用性。

  • 性能优化:减少了因 Rebalance 导致的消费者组不稳定和性能下降,特别是在消费者组规模较大或者有频繁变动时,效果更为显著。

  • 黏性分配优化:尽管保持了黏性,但相比于传统的 StickyAssignor,CooperativeStickyAssignor 在 Rebalance 后能更有效地平衡分区的分配,避免某些消费者过载或空闲的情况。

  • 28
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值