问题

用过 Kafka 的同学用过都知道,每个 Topic 一般会有很多个 partitions。为了使得我们能够及时消费消息,我们也可能会启动多个 Consumer 去消费,而每个 Consumer 又会启动一个或多个streams去分别消费 Topic 里面的数据。我们又知道,Kafka 存在 Consumer Group 的概念,也就是 group.id 一样的 Consumer,这些 Consumer 属于同一个Consumer Group,组内的所有消费者协调在一起来消费订阅主题(subscribed topics)的所有分区(partition)。当然,每个分区只能由同一个消费组内的一个consumer来消费。那么问题来了,同一个 Consumer Group 里面的 Consumer 是如何知道该消费哪些分区里面的数据呢?

如果想及时了解Spark、Hadoop或者Hbase相关的文章,欢迎关注微信公共帐号:iteblog_hadoop

如上图,Consumer1 为啥消费的是 Partition0 和 Partition2,而不是 Partition0 和 Partition3?这就涉及到 Kafka 内部分区分配策略(Partition Assignment Strategy)了。

在 Kafka 内部存在两种默认的分区分配策略:Range 和 RoundRobin。当以下事件发生时,Kafka 将会进行一次分区分配:

  • 同一个 Consumer Group 内新增消费者

  • 消费者离开当前所属的Consumer Group,包括shuts down 或 crashes

  • 订阅的主题新增分区

将分区的所有权从一个消费者移到另一个消费者称为重新平衡(rebalance),如何rebalance就涉及到本文提到的分区分配策略。下面我们将详细介绍 Kafka 内置的两种分区分配策略。本文假设我们有个名为 T1 的主题,其包含了10个分区,然后我们有两个消费者(C1,C2)来消费这10个分区里面的数据,而且 C1 的 num.streams = 1,C2 的 num.streams = 2。

Range strategy

Range策略是对每个主题而言的,首先对同一个主题里面的分区按照序号进行排序,并对消费者按照字母顺序进行排序。在我们的例子里面,排完序的分区将会是0, 1, 2, 3, 4, 5, 6, 7, 8, 9;消费者线程排完序将会是C1-0, C2-0, C2-1。然后将partitions的个数除于消费者线程的总数来决定每个消费者线程消费几个分区。如果除不尽,那么前面几个消费者线程将会多消费一个分区。在我们的例子里面,我们有10个分区,3个消费者线程, 10 / 3 = 3,而且除不尽,那么消费者线程 C1-0 将会多消费一个分区,所以最后分区分配的结果看起来是这样的:

C1-0 将消费 0, 1, 2, 3 分区C2-0 将消费 4, 5, 6 分区C2-1 将消费 7, 8, 9 分区

假如我们有11个分区,那么最后分区分配的结果看起来是这样的:

C1-0 将消费 0, 1, 2, 3 分区C2-0 将消费 4, 5, 6, 7 分区C2-1 将消费 8, 9, 10 分区

假如我们有2个主题(T1和T2),分别有10个分区,那么最后分区分配的结果看起来是这样的:

C1-0 将消费 T1主题的 0, 1, 2, 3 分区以及 T2主题的 0, 1, 2, 3分区C2-0 将消费 T1主题的 4, 5, 6 分区以及 T2主题的 4, 5, 6分区C2-1 将消费 T1主题的 7, 8, 9 分区以及 T2主题的 7, 8, 9分区

可以看出,C1-0 消费者线程比其他消费者线程多消费了2个分区,这就是Range strategy的一个很明显的弊端。

RoundRobin strategy

使用RoundRobin策略有两个前提条件必须满足:

  • 同一个Consumer Group里面的所有消费者的num.streams必须相等;

  • 每个消费者订阅的主题必须相同。

所以这里假设前面提到的2个消费者的num.streams = 2。RoundRobin策略的工作原理:将所有主题的分区组成 TopicAndPartition 列表,然后对 TopicAndPartition 列表按照 hashCode 进行排序,这里文字可能说不清,看下面的代码应该会明白:

val allTopicPartitions = ctx.partitionsForTopic.flatMap { case(topic, partitions) =>  info("Consumer %s rebalancing the following partitions for topic %s: %s"       .format(ctx.consumerId, topic, partitions))  partitions.map(partition => {    TopicAndPartition(topic, partition)  })}.toSeq.sortWith((topicPartition1, topicPartition2) => {  /*   * Randomize the order by taking the hashcode to reduce the likelihood of all partitions of a given topic ending   * up on one consumer (if it has a high enough stream count).   */  topicPartition1.toString.hashCode < topicPartition2.toString.hashCode})

最后按照round-robin风格将分区分别分配给不同的消费者线程。

在我们的例子里面,加入按照 hashCode 排序完的topic-partitions组依次为T1-5, T1-3, T1-0, T1-8, T1-2, T1-1, T1-4, T1-7, T1-6, T1-9,我们的消费者线程排序为C1-0, C1-1, C2-0, C2-1,最后分区分配的结果为:

C1-0 将消费 T1-5, T1-2, T1-6 分区;C1-1 将消费 T1-3, T1-1, T1-9 分区;C2-0 将消费 T1-0, T1-4 分区;C2-1 将消费 T1-8, T1-7 分区;

多个主题的分区分配和单个主题类似,这里就不在介绍了。

根据上面的详细介绍相信大家已经对Kafka的分区分配策略原理很清楚了。不过遗憾的是,目前我们还不能自定义分区分配策略,只能通过partition.assignment.strategy参数选择 range 或 roundrobin。partition.assignment.strategy参数默认的值是range。

转载于:https://www.cnblogs.com/bigben0123/p/10640837.html

Kafka分区分配策略(Partition Assignment Strategy相关推荐

  1. Kafka分区分配策略(Partition Assignment Strategy)

    问题 用过 Kafka 的同学用过都知道,每个 Topic 一般会有很多个 partitions.为了使得我们能够及时消费消息,我们也可能会启动多个 Consumer 去消费,而每个 Consumer ...

  2. kafka的分区策略(partition assignment strategy)

    概述 kafka的分区策略指的是producer端的 各个partition中的数据如何安排给consumer消费. Range(按范围) ange策略是对每个主题而言的,首先对同一个主题里面的分区按 ...

  3. Kafka分区分配策略(2)——RoundRobinAssignor和StickyAssignor

    接上文[Kafka分区分配策略(1)--RangeAssignor] 欢迎支持笔者新作:<深入理解Kafka:核心设计与实践原理>和<RabbitMQ实战指南>,同时欢迎关注笔 ...

  4. 9.Kafka 分区分配策略(Range分配策略 RoundRobin分配策略)

    前言 在 Kafka 实际生产过程中,每个 topic 都会有 多个 partitions.   1.多个Partitions有什么好处? ①多个 partition ,能够对 broker 上的数据 ...

  5. Kafka分区分配策略(3)——自定义分区分配策略

    接上文: 1.[Kafka分区分配策略(1)--RangeAssignor] 2.[Kafka分区分配策略(2)--RoundRobinAssignor和StickyAssignor] 欢迎支持笔者新 ...

  6. Kafka分区分配策略(4)——分配的实施

    接上文: 1.[Kafka分区分配策略(1)--RangeAssignor] 2.[Kafka分区分配策略(2)--RoundRobinAssignor和StickyAssignor] 3.[Kafk ...

  7. Kafka分区分配策略(1)——RangeAssignor

    欢迎支持笔者新作:<深入理解Kafka:核心设计与实践原理>和<RabbitMQ实战指南>,同时欢迎关注笔者的微信公众号:朱小厮的博客. 欢迎跳转到本文的原文链接:https: ...

  8. Kafka分区分配策略以及重平衡过程总结

    Kafka自身提供了三种分区分配策略,通过消费者端配置参数partition.assignment.strategy来控制. 1.RangeAssignor分配策略(kafka默认的分区策略) 通过配 ...

  9. kafka分区分配策略

    kafka的分区分配策略大概可以分为一下几步: 前置条件: a.假设消费者组到对应的server的GroupCordinator是已知的,这个groupCordinator和消费组对应的_offset ...

  10. kafka partition分配_kafka的分区分配策略

    用过 Kafka 的同学应该都知道,每个 Topic 一般会有很多个 partitions.为了使得我们能够及时消费消息,我们也可能会启动多个 Consumer 去消费,而每个 Consumer 又会 ...

最新文章

  1. 学校计算机机房好处,浅谈学校计算机机房维护
  2. 使用rsync同步linux服务器上的文件到windows上
  3. 东师计算机应用基础18秋在线作业3答案,奥鹏东师计算机应用基础15秋在线作业3试卷及答案(4)...
  4. SAP Fiori Application Generator 在 Visual Studio Code 启动时遇到的错误消息
  5. 性能优化8--内存泄露
  6. 模板引擎的简单原理template
  7. R 语言学习(二)—— 向量
  8. 北风:信息差有多重要?你是怎么被割韭菜的?
  9. 一分钟快速制作电子签名
  10. 微服务swoft打造腾讯云短信网关
  11. 图片标签格式的转换:TXT转为XML,PNG转为JPG格式
  12. devise 自定义手机号登录
  13. android4.4 音量控制,android4.4调整音量调节速度
  14. VMware 兼容性列表与产品互操作性列表使用收集(持续更新中...)
  15. HRM认证授权方案_新版
  16. 5G网络安全认证体系研究
  17. CRC32原理及实现学习
  18. 华为是否关闭私有云,这个问题真的那么重要么?
  19. 大数据全套教学视频,看仔细了是视频!
  20. 命令行下配置代理服务器

热门文章

  1. python 实现两个excel表格数据的对比
  2. ping包优化版本python
  3. python3 centos7-linux 安装
  4. java--小示例:-3-可以作为测试内容使用
  5. Kettle JAVA代码表达式
  6. java hadoop makefile_makefile高级用法--make 的运行
  7. 相机标定 棋盘格 图_【连载2.3.1】结构光系统标定
  8. IEEE745浮点数格式
  9. 智能家居规模发展尚需时日
  10. ios入门之消息推送详解