kafka分区策略

  其他常见问题
内容纲要

概要描述


在kafka中,每个topic一般会有很多个Partitions。为了使我们能够及时的消费消息, 我们也可能启动多个Consumer去消费分区,而每个Consumer同样会启动一个或者是多个streams去分别消费Topic里面的数据。在Kafka中存在着Consumer Group的概念。topic也有分区的概念。那么同一个Consumer Group里面的Consumer是如何知道该去消费哪些分区里面的数据呢?

详细说明


file

就像上面图示, Consumer 1 为什么消费的是Partition0 和Partition2呢?而不是消费的Partition0和Partition3呢?或者是其他呢?这就涉及到Kafka内部分配策略(Partition Assignment Strategy)

说到Kafka分区分配策略,就是它的内部的默认的分区分配策略:Range 和 RoundRobin(轮询)。当下面的事情发生的时候,Kafka将会进行一次分区分配。

    1、当同一个Consumer Group 内新增消费者。(消费者层面发生改动)

    2、消费者离开当前所属的Consumer Group,包括Shuts down(关闭、停工)或者是crashes(崩溃)。(消费者层面发生改动)

    3、就是消费者订阅的主题新增分区的时候

将分区的所有权从一个消费者移到另一个消费者成为重新平衡(rebalance),如何rebalance就涉及到分区分配策略。

假设有一个名为Top1的主题,它有十个分区,然后有两个消费者(C1、C2)来消费这十个分区里面的数据,而且C1的num.streams=1,C2的num.streams=2。

Range Strategy(根据范围消费)

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

C1-0将消费0,1,2,3分区

C2-0将消费4,5,6分区

C2-1将消费7,8,9分区

如果有第十一个分区的话,那么分区是这样的

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

C2-1将消费8,9,10分区

如果我们有2个主题(T1和T2),分别都有十个分区,那么最后的分配结果是:

 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消费者线程比其他消费者线程多消费了两个分区,这就是Range Strategy的一个明显的弊端。 当分区很多的时候,会有个别的线程压力巨大!

RoundRobin strategy(轮询的消费策略)

在使用RoundRobin Strategy的时候我们必须满足两个条件:

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

2、每个消费者订阅的主题必须相同

在这里我们假设2个消费者的num.streams=2. RoundRobin strategy的工作原理: 将所有主题的分区组成TopicAndPartition列表,然后对TopAndPartition列表按照hashcode进行排序。

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

在我们的例子中,假如按照hashcode排序完的topic-partition组依次为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分区;

目前我们还不能自定义分区分配策略,只能通过partition.assignment.strategy参数选择range或roundrobin。
TDH的partition.assignment.strategy参数默认的值是Roundrobin。

这篇文章对您有帮助吗?

平均评分 0 / 5. 次数: 0

尚无评价,您可以第一个评哦!

非常抱歉,这篇文章对您没有帮助.

烦请您告诉我们您的建议与意见,以便我们改进,谢谢您。