有关卡夫卡分区者的关键细节
#dotnet #java #apachekafka

ApacheKafka®是今天事件流的事实上的标准。使Kafka如此成功的部分原因是它可以处理大量数据的能力,其吞吐量每秒数百万张记录,而不是生产环境中闻所未闻的。 Kafka设计的一部分使这可能是分区。

kafka使用分区将数据负载分布在集群中的经纪人之间,也是并行性的单位。更多的分区意味着更高的吞吐量。由于Kafka与键值对合作,因此在同一分区上获得相同键的记录至关重要。

想想使用客户ID用于为Kafka生产的每个交易的银行应用程序。将所有这些事件都放在同一分区上至关重要。这样,消费者应用程序按照其到达的顺序处理记录。在正确的分区上保证具有相同关键土地的记录的机制是一个简单但有效的过程:取下隔板数量的关键模型。这是一个显示此概念在行动中的例证:

Partitioners use hashing to determine the correct partition for a key

在高级别上,诸如CRC32或Murmur2之类的哈希函数采用输入,并产生固定尺寸的输出,例如64位数字。无论是在Java,Python还是任何其他语言中实现的,相同的输入总是会产生相同的输出。分区者使用哈希结果始终选择分区,因此相同的记录密钥将始终映射到同一Kafka分区。我将在此博客中详细介绍更多细节,但是足以知道可以使用几种哈希算法。

我今天想谈论分区的工作原理,而是想谈论卡夫卡生产者客户的分区。生产者使用分区器来确定给定密钥的正确分区,因此在生产者客户端中使用相同的分区策略至关重要。

由于生产者客户端具有默认分区设置,因此此要求不应该是问题。例如,当将Java生产者客户端与Apache Kafka发行版一起使用时,KafkaProducer类提供了一个默认分区,uses the Murmur2 hash function确定给定键的分区。

但是,其他语言的Kafka生产者客户呢?出色的librdkafka project是KAFKA客户端的C/C ++实现,广泛用于非JVM KAFKA应用程序。此外,其他语言的Kafka客户端(Python,C#)在其顶部建立。 librdkafka的默认分区器使用CRC32哈希功能来获取键的正确分区。

这种情况本身并不是问题,但很容易出现。 Kafka经纪人对客户的语言不可知。只要它遵循KAFKA协议,您就可以使用任何语言的客户,并且经纪人愉快地接受他们的农产品并消费请求。 Python和Java说,鉴于当今的多语言编程环境,您可以在以不同语言工作的组织中建立开发团队。但是,如果没有任何更改,这两个组最终都会以不同的哈希算法的形式使用不同的分区策略:具有Murmur2的CRC32和Java生产商的Librdkafka生产商,因此具有相同密钥的记录将在不同的分区中降落!那么,对这种情况有什么补救措施?

Java KafkaProducer仅通过默认分区提供一个哈希算法;由于实施分区器很棘手,因此最好将其留在默认情况下。但是librdkafka producer client provides multiple options。这些选项之一是Murmur2_random分区器,它使用murmur2 hash函数,并将null键分配给随机分区,将等效行为(与Java默认分区者)分配。

例如,如果您在C#中使用Kafka生产者客户端,则可以使用此行设置分区策略:

ProducerConfig.Partitioner = Partitioner.Murmur2Random;

现在您的C#和Java生产者客户使用兼容分区方法!

使用非Java Kafka客户端时,启用与Java生产者客户端相同的分区策略是一个绝佳的想法,可以确保所有生产者对不同键使用一致的分区。