大数据之Kafka:Kafka架构深入之生产者和消费者的分区分配策略

引言
我们都知道在kafka中producer向topic推送消息,而consumer是主动去拉取消息。而在topic中存在着分区和分片,那么kafka生产者和消费者应该采用什么样的分区分配策略呢?
一、producer的分区分配策略
我们向topic发送消息的时候是要把messages封装成一个ProducerRecord对象的,源码如下:
在这里插入图片描述
(1)可以看到后面4种是需要我们自己指定分区的,所以可以直接将消息发送到指定分区
(2)第二行需要我们指定一个key,这种是将key的hash值与topic的partition数求余得到分区值,是不知道会发往哪一个分区的
(3)而第一行是你既没有指定partition又没有指定key的值,第一次调用时会随机生成一个整数(后面每次调用在这个整数上自增),将这个值与topic的 partition数取余得到partition值,也就是常说的 round-robin 算法,这也是默认的分区分配策略,能够保证负载均衡

二、consumer的分区分配策略
我们都知道consumer是以consumer group的名义订阅topic,而topic中有多个partition,consumer group中又有多个consumer,那么consumer和partition之前的对应关系又是怎样的呢?
换句话说,就是同一个consumer group中的每一个consumer应该负责哪些分区,这个分配关系又是如何确定的呢?
我们都知道一个partition只能被一个consumer消费,这能保证不重复消费消息和顺序消费分区里面的数据

可以看到org.apache.kafka.clients.consumer.internals.AbstractPartitionAssignor这个类默认有3种实现方式,如果要自定义分配策略的话,只需要继承AbstractPartitionAssignor这个类
在这里插入图片描述
1、Range策略
range策略对应的实现类org.apache.kafka.clients.consumer.RangeAssignor
,同时这是默认的分配策略可以通过consumer配置partition.assignment.strategy参数来指定分配策略,它的值是类的全路径,是一个数组
官方解释如下:
在这里插入图片描述
意思就是一个group中的两个consumer同时订阅了两个topic,这两个topic都有3个分区,其他一个consumer被分配到了t0p0, t0p1, t1p0, t1p1,另一个consumer被分配到了t0p2, t1p2,那么为什么会这样分配呢?

这是因为range策略是基于主题进行划分分区的
对于每个主题,我们以数字顺序排列可用分区,以字典顺序排列消费者。然后,将分区数量除以消费者总数,以确定分配给每个消费者的分区数量。如果没有平均划分(有余数),那么最初的几个消费者将有一个额外的分区。
简而言之,就是:

1、range分配策略针对的是主题(也就是说,这里所说的分区指的某个主题的分区,消费者指的是订阅这个主题的消费者组中的所有消费者)
2、首先,将分区按数字顺序排行序,消费者按消费者名称的字典序排好序,然后,用分区总数除以消费者总数。如果能够除尽,则皆大欢喜,平均分配
3、若除不尽,则位于排序前面的消费者将多负责一个分区

2、RoundRobin(轮询)策略
roundronbin分配策略的具体实现是org.apache.kafka.clients.consumer.RoundRobinAssignor
在这里插入图片描述
意思就是一个group中的两个consumer同时订阅了两个topic,这三个topic都有3个分区,其中一个consumer被分配到了t0p0, t0p2, t1p1,另一个consumer被分配到了t0p1, t1p0, t1p2,那么为什么会这样分配呢?

这是因为轮询分配策略是基于所有可用的消费者和所有可用的分区的,与前面的range策略最大的不同就是它不再局限于某个主题,如果所有的消费者实例的订阅都是相同的,那么这样最好了,可用统一分配,均衡分配
假设,组中每个消费者订阅的主题不一样,分配过程仍然以轮询的方式考虑每个消费者实例,但是如果没有订阅主题,则跳过实例。当然,这样的话分配肯定不均衡。

什么意思呢?也就是说,消费者组是一个逻辑概念,同组意味着同一时刻分区只能被一个消费者实例消费,换句话说,同组意味着一个分区只能分配给组中的一个消费者。事实上,同组也可以不同订阅,这就是说虽然属于同一个组,但是它们订阅的主题可以是不一样的。

根据上面的文档我们是不是还看到一种情况:有3个主题t0、t1、t2,有3个消费者c0、c1、c2。然而c0只订阅到t0,c1订阅t0、 t1,c2订阅t0、t1、t2。其中t0有1个分区p0,t1有2个分区p0、p1,t2有3个分区p0、p1、p2,最后c0消费t0p0,c1消费t1p0,c2消费t1p1、 t2p0、t2p1,、t2p2,那为什么会这样呢?

首先,肯定是轮询的方式,t0p0只在c0中轮询,t1p0、t1p2在c1、c2中轮询,t2p0、t2p1、t2p2只在c2中轮询,结果是不是就是上面的结果
参考:https://blog.csdn.net/wjt199866/article/details/108375978

猜你喜欢

转载自blog.csdn.net/weixin_43597208/article/details/115260186