【Kafka】flinkProducer kafka分区策略及kafka 默认分区策略

5 篇文章 2 订阅

前言

最近在学习Flink 读写 Kafka, 突然想到如果 Flink 生产消息到Kafka,那么这条消息如何确定发往那个分区。顺便也回顾下 Kafka 本身一个默认分区策略和生产策略这里整理并记录下。

  • Flink 1.15
  • Kafka 2.7

一、KafkaSink

FlinkKafkaProducer 已在 Flink 1.15 中删除 ,所以下文使用的 KafkaSink

1. 默认

这里我们使用 KafkaSink 来将数据写入到 Kafka,那么KafkaSink 是如何确定一条消息要发送到那个分区?默认的策略是什么?

在这里插入图片描述

可以看到 KafkaSink 只有 FlinkFixedPartitioner 这一个默认的实现。

相关的分区策略代码如下:
在这里插入图片描述

public int partition(T record, byte[] key, byte[] value, String targetTopic, int[] partitions) {
        Preconditions.checkArgument(partitions != null && partitions.length > 0, "Partitions of the target topic is empty.");
        return partitions[this.parallelInstanceId % partitions.length];
    }

可以看出 FlinkKafkaProducer 是根据Flink运行子任务的并行度进行分区数的取余写入的。计算公式如下。

partitions = parallelInstanceId % partitions.length

总结:Flink 默认的分区策略是并行度Id 与topic 分区数取模的结果,但是这样如果 并行度数 % partitions.length != 0 ,那么势必会造成分区负载不均衡。

二、Kafka 默认的分区策略

只针对Kafka来说,如何确认一条消息发送的分区?

Kafka2.4 前

对于Kafka 2.4 版本来说,有以下几个方式确定数据发送的分区。

  1. 非 key 写入的情况下,使用 轮询 (round-robin) 的方式进行分区。
  2. 有 key 写入的情况下,使用 哈希 (murmur2 哈希算法)的方式进行分区。
  3. 代码中指定消息写入的分区。

Kafka 2.4 后

  1. 非 key 写入的情况下,使用 粘性(StickyPartitioning Strategy) 的方式进行分区。
  2. 有 key 写入的情况下,使用 哈希 (murmur2 哈希算法)的方式进行分区。
  3. 代码中指定消息写入的分区。
StickyPartitioning Strategy

Kafka 2.4 之前的旧分区策略是循环遍历主题的分区并向每个分区发送一条记录。不幸的是,这种方法不能很好地批处理,实际上可能会增加延迟。

粘性分区器的主要目标是增加每个批次中的记录数,以减少批次总数并消除过度排队。当批次较少且每个批次中的记录较多时,每条记录的成本较低,并且使用粘性分区策略可以更快地发送相同数量的记录。

StickyPartitioning Strategy会随机地选择另一个分区并会尽可能地坚持使用该分区——即所谓的粘住这个分区

一旦该分区的批次被填充或以其他方式完成,粘性分区器会随机选择并“粘贴”到新分区。这样,在更长的时间内,记录大致均匀分布在所有分区中

粘性分区器通过选择单个分区来发送所有非键记录,解决了将没有键的记录分散到更小的批次中的问题。

当 Kafka 生产者向主题发送记录时,它需要决定将其发送到哪个分区。如果我们几乎同时将几条记录发送到同一个分区,它们可以作为一个批次发送。处理每个批次需要一些开销,批次中的每条记录都会导致该成本。小批量的记录每条记录的有效成本更高。通常,较小的批次会导致更多的请求和排队,从而导致更高的延迟。

在这里插入图片描述

总结

  1. 如果不单独设置 partition 策略,会默认使用 FlinkFixedPartitioner,该 partitioner 分区的方式是 task 所在的并发 id 对 topic 总 partition 数取余:parallelInstanceId % partitions.length
  2. 如果构建 FlinkKafkaProducer 时,setPartition 设置为 null,此时会使用 kafka producer 默认分区方式。
  3. 对于 Kafka2.4 版本前:
    非 key 写入的情况下,使用 round-robin 的方式进行分区,每个 task 都会轮循的写下游的所有 partition。该方式下游的 partition 数据会比较均衡。
    带key 写入的情况下,使用 哈希算法。
  4. 对于 Kafka2.4 版本后:
    key 写入的情况下,使用 粘性分区算法 的方式进行分区。会随机指定一个分区,并尽可能往这个分区,同样使用该方式下游的 partition 数据也会比较均衡。
    key 写入的情况下,使用 哈希算法。

参考:

  • https://www.confluent.io/blog/apache-kafka-producer-improvements-sticky-partitioner/
  • https://nightlies.apache.org/flink/flink-docs-release-1.15/zh/docs/connectors/table/kafka/
  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
Kafka是一款高性能的分布式消息系统,它使用分区来实现消息的并行处理和负载均衡。Kafka分区策略的设计和优化对于提高Kafka的性能和可靠性非常重要,下面是Kafka分区策略及优化的一些建议: 1. 分区数量的选择:Kafka分区数量应该根据实际业务情况和硬件资源来选择。通常建议分区数量为总消费者数的2-3倍,这样可以保证所有消费者都可以获取到消息,并且在需要扩容时也更方便。 2. 分区的负载均衡:Kafka使用的是分布式消费者组的方式来实现负载均衡,但是如果分区数量过少或者消费者数量过多,可能会导致分区的负载不均衡。可以通过增加分区数量或者减少消费者数量来解决这个问题。 3. 分区的复制策略Kafka支持分区数据的复制,可以提高可靠性和容错性,但是也会增加系统的负载。在分区数量较多的情况下,建议适当减少分区的复制数,以提高系统的性能。 4. 分区的大小和存储:Kafka分区大小和存储空间也会影响系统的性能和可靠性。建议根据实际业务情况来选择合适的分区大小和存储空间,以保证系统的性能和可靠性。 5. 分区的备份策略Kafka的备份策略可以选择同步或异步备份,同步备份可以保证数据的一致性和可靠性,但是会影响系统的性能。建议根据实际业务情况来选择合适的备份策略,以保证系统的性能和可靠性。 总的来说,Kafka分区策略的设计和优化需要根据实际业务情况和系统资源来选择合适的参数和策略,以提高系统的性能和可靠性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值