前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >kafka消费者分区分配策略

kafka消费者分区分配策略

原创
作者头像
大数据架构师
修改2021-11-05 09:19:45
7840
修改2021-11-05 09:19:45
举报
文章被收录于专栏:Kafka系列

概述

kakfa的topic有多个partition,而消费端是以消费组为单元进行分区的消息,那么如何将一个topic下面的partition合理的分配给消费者中的消费者。Kafka有几种分配策略

RangeAssignor

RangeAssignor 策略是基于每个topic之上的,对于每个topic而言,kafka 列出可用的分区,对于每个topic,我们按数字顺序排列可用分区,以消费者的名称的词典顺序列出消费者。然后,我们将分区数量除以消费者总数,以确定分配给每个消费者的分区数量。如果它不均匀地划分,那么前几个消费者将有一个额外的分区。

如下图,有topic t1 和 消费组,t1 有四个分区,消费组有三个消费者。

分区依次为:t1.p0,t1.p1,t1.p2,t1.p3

假设N = 分区数,M=消费者数量

N/M = 4/3 = 1

N%M = 4%3 = 1

分配:前(N%M)个消费者,分配N+1(1+1) = 2 个分区,其余的消费者分配 N 个

所以,最终的分配结果就是:

c0: t1.p0,t1.p1

c1: t1.p2

c2:t1.p3

如果同时订阅了多个主题,则按每个主题分配后,会出现不均衡的情况,如下图,有两个主题t1和t2

分配后的结果为:

c0: t1.p0, t1.p1, t2.p0,t2.p1

c1: t1.p2, t2.p2

c2: t1.p3, t2,p3

RoundRobinAssignor

循环赋值器列出所有可用分区和所有可用使用者。然后,它继续执行从分区到使用者的循环分配。如果所有使用者实例的订阅都相同,则分区将均匀分布。(即,所有使用者的分区所有权计数都将在正好1的增量范围内。)

如上图,假设有两个消费者C0和C1,两个主题t0和t1,每个主题有3个分区,从而得到分区t0p0、t0p1、t0p2、t1p0、t1p1和t1p2。

分配结果为:

  • C0: [t0p0, t0p2, t1p1]
  • C1: [t0p1, t1p0, t1p2]

如上图,当消费者实例之间的订阅不同时,分配过程仍然以循环方式考虑每个用户实例,但如果实例未订阅主题,则跳过该实例。与订阅相同的情况不同,这可能导致分配不平衡。例如,我们有三个消费者C0、C1、C2和三个主题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]

由于引入了静态成员身份,我们可以利用group.instance.id使分配行为更具粘性。例如,我们有三个消费者,分配了member.id C0、C1、C2、两个主题t0和t1,每个主题有3个分区,从而产生了分区t0p0、t0p1、t0p2、t1p0、t1p1和t1p2。我们选择根据ephemeral member.id执行排序顺序。如下图:

分配结果为:

C0: [t0p0, t1p0]

C1: [t0p1, t1p1]

C2: [t0p2, t1p2] 组协调员将尝试向使用者分配新的

在一次重新均衡后,组协调员将尝试向使用者分配新的memberid,例如C0->C5 C1->C3,C2->C4。 任务可以完全转移到, 如下图:

C4(是 C2):[t0p1,t1p1](在was[t0p2,t1p2]之前)

C3(是C1):[t0p0,t1p0](之前是[t0p1,t1p1])

C5(是C0):[t0p2,t1p2](之前是[t0p0,t1p0])

这个问题可以通过引入静态成员来缓解。 消费者将拥有单独的实例 ID I1、I2、I3。 只要

1. 跨代成员数量保持不变 2. 静态成员的身份跨代保持不变 3. 任何成员的订阅模式都不会改变

分配结果一直会是:

I0: [t0p0, t1p0]

I1: [t0p1, t1p1]

I2: [t0p2, t1p2]

StickyAssignor

粘性分配器有两个目的。首先,它保证分配尽可能平衡,它有两个目的:

  • 分配给消费者的topic partition个数最多相差1个;或者
  • 主题分区比其他消费者少 2+ 的每个消费者无法将这些主题分区中的任何一个转移到它。

其次,当发生重新分配时,它尽可能多地保留现有分配。当主题分区从一个消费者移动到另一个消费者时,这有助于节省一些开销处理。

重新开始它可以通过将分区尽可能均匀地分布在消费者身上来工作。尽管这听起来与循环分配器的工作方式相似,但下面的第二个示例表明事实并非如此。在重新分配期间,它将以这样一种方式执行重新分配,即在新分配中

  1. 主题分区仍然尽可能均匀地分布
  2. 主题分区尽可能地保留在其先前分配的消费者中。

当然,上面的第一个目标优先于第二个目标。

例 1.假设有 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被删除并且重新分配即将发生。

循环分配器将产生:

  • C0: [t0p0, t1p0, t2p0, t3p0]
  • C2: [t0p1, t1p1, t2p1, t3p1]

而粘性分配器会导致:

  • C0 [t0p0, t1p1, t3p0, t2p0]
  • C2 [t1p0, t2p1, t0p1, t3p1]

保留所有以前的分配(与循环分配器不同)

示例 2.有 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]

这不像粘性分配器建议的分配那样平衡:

  • C0 [t0p0]
  • C1 [t1p0, t1p1]
  • C2 [t2p0, t2p1, t2p2]

现在如果消费者C0被移除,这两个分配器将产生以下分配。

循环(保留 3 个分区分配):

  • C1 [t0p0, t1p1]
  • C2 [t1p0, t2p0, t2p1, t2p2]

粘性(保留 5 个分区分配):

  • C1 [t1p0, t1p1, t0p0]
  • C2 [t2p0, t2p1, t2p2]

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 概述
  • RangeAssignor
  • RoundRobinAssignor
  • StickyAssignor
相关产品与服务
即时通信 IM
即时通信 IM(Instant Messaging)基于腾讯二十余年的 IM 技术积累,支持 Android、iOS、Mac、Windows、Web、H5、小程序平台且跨终端互通,低代码 UI 组件助您30分钟集成单聊、群聊、好友与资料、消息漫游、群组管理、会话管理、直播弹幕、内容审核和推送等能力。适用于直播互动、电商带货、客服咨询、社交沟通、企业办公、互动游戏、医疗健康等场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档