kafka生产者分区策略选择

kafka生产者分区策略选择没有明确的答案, 官方提供了三个分区策略器:

  • 1. DefaultPartitioner 默认分区策略
    • 粘性分区Sticky Partitioner
  • 2.UniformStickyPartitioner 纯粹的粘性分区策略
  • 3. RoundRobinPartitioner 分区策略

KafkaProducer在发送消息的时候,需要指定发送到哪个分区(不是说你的代码一定要指定), kafka自带的分区策略说明如下,

1. DefaultPartitioner 默认分区策略

全路径类名:org.apache.kafka.clients.producer.internals.DefaultPartitioner

  • 如果消息中指定了分区(业务代码send消息时),则使用该分区
  • 如果未指定分区但存在key,则根据序列化key使用murmur2哈希算法对分区数取模。
  • 如果不存在分区也不存在key,则会使用粘性分区策略.

粘性分区Sticky Partitioner

为什么会有粘性分区的概念?

首先,我们指定,Producer在发送消息的时候,会将消息放到一个ProducerBatch中, 这个Batch可能包含多条消息,然后再将Batch打包发送。这样做的好处就是能够提高吞吐量,减少发起请求的次数。

但是有一个问题就是, 因为消息的发送它必须要你的一个Batch满了或者linger.ms时间到了,才会发送。如果生产的消息比较少的话,迟迟难以让Batch塞满,那么就意味着更高的延迟。

在之前的消息发送中,是将消息轮询或者hash到各个分区的,那么每个ProducerBatch都很难满足条件batch条件,即难以使用batch的优势。

那么假如我先让一个ProducerBatch塞满了之后,再给其他的分区分配是不是可以降低这个延迟呢?

详细的可以看看下面这张图、这张图的前提是:

Topic1 有3分区, 此时给Topic1 发9条无key的消息, 这9条消息加起来都不超过batch.size . 那么以前的分配方式和粘性分区的分配方式如下:

可以看到,使用粘性分区之后,至少是先把一个Batch填满了发送然后再去填充另一个Batch。不至于向之前那样,虽然平均分配了,但是导致一个Batch都没有放满,不能立即发送。这不就增大了延迟了吗(只能通过linger.ms时间到了才发送)

划重点:

  1. 粘性的目的是为了充分使用batch机制.
  2. 当一个Batch发送之后,需要选择一个新的粘性分区的时候 ①. 可用分区<1 ;那么选择分区的逻辑是在所有分区中随机选择。②. 可用分区=1;那么直接选择这个分区。③. 可用分区>1 ; 那么在所有可用分区中随机选择。
  3. 当选择下一个粘性分区的时候,不是按照分区平均的原则来分配。而是随机原则(当然不能跟上一次的分区相同)
    例如刚刚发送到的Batch是 1号分区,等Batch满了,发送之后,新的消息可能会发到2或者3, 如果选择的是2,等2的Batch满了之后,下一次选择的Batch仍旧可能是1,而不是说为了平均,选择3分区。

粘性问题:

  1. 选择下一个可用分区时并不是按照轮询策略,即可能出现两个分区不断轮换,第三个分区负载很低,从而出现大量数据倾斜.
  2. 如果消息并发很高,就很容易达到所有分区的batch大小,此时只需要设置linger.ms=几毫秒,不需要使用粘性分区,也能充分利用batch.

2.UniformStickyPartitioner 纯粹的粘性分区策略

全路径类名:org.apache.kafka.clients.producer.internals.UniformStickyPartitioner

他跟DefaultPartitioner 分区策略的唯一区别就是。

DefaultPartitionerd 如果有key的话,那么它是按照key来决定分区的,这个时候并不会使用粘性分区 UniformStickyPartitioner 是不管你有没有key, 统一都用粘性分区来分配。

其优缺点等同于无key条件下的DefaultPartitioner.

3. RoundRobinPartitioner 轮询分区策略

全路径类名:org.apache.kafka.clients.producer.internals.RoundRobinPartitioner

  • 将消息平均分配到每个分区中,不受性能影响。
  • 与key无关

总结:

根据以上描述,我们知道,不同场景应该选择不同的分区器, 一般情况下选择默认分区器(DefaultPartitioner),无论是否高并发,如果极致追求数据平均分布,选择轮询分区器(RoundRobinPartitioner).粘性分区策略(StickyPartitioner)高并发下不需要,低并发下有无batch无所谓,可能在中等并发下有一点使用场景.

注意:

粘性策略是kafka2.4中引入的,所以要使用其特性,就需要使用2.4+版本的客户端,服务器端不一定要2.4+,因为kafka从1.x开始就没有本质上的改变.故新客户端是可以操作旧服务器端的,而且分区策略器是生产者客户端干的事情,与服务器端没什么大关系(仅需获取分区列表).

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值