在多线程的情况下,Kafka 中的排序保证

Ordering guarantees in Kafka in case of multiple threads

据我了解,如果我们想按顺序写入/读取记录,Kafka 生产者和消费者都必须为每个主题分区使用一个线程。我是对的,还是他们在这种情况下使用多线程?

因此在单线程和多线程环境中的 Kafka 中都可以实现排序

单broker/single分区->基于单线程的消费者模型

Kafka 中的消息顺序适用于单个分区。但是对于单个分区,很难实现并行和负载均衡。请注意,在这种情况下,只有一个线程将用于访问主题分区,因此始终保证顺序。

多个 brokers/multiple 分区 -> 基于多线程的消费者模型(拥有超过 1 个消费者的消费者组)

在这种情况下,我们假设主题中存在多个分区,并且每个分区由每个消费者组中的单个消费者(准确地说是单个线程)处理,这被称为多线程。

在 Kafka 中,我们可以通过三种方法来保留分区内消息的顺序。每种方法都各有利弊。

方法一:循环或喷洒
方法 2:散列密钥分区
方法 3:自定义分区程序

循环或喷洒(默认)
在这种方法中,分区将以 round-robin 的方式向所有分区发送消息,确保服务器负载均衡。不会发生任何分区的过载。通过这种方法实现了并行和负载均衡,但不能保持整体顺序,但会保持分区内的顺序。这是默认方式,不适合部分业务场景。

为了克服上述情况并保持消息顺序,让我们尝试另一种方法。

散列密钥分区
在这个方法中,我们可以创建一个 ProducerRecord,指定一个消息键,每条消息都被传递到主题,以确保分区排序将会发生。 默认分区将使用密钥的哈希值来确保同一密钥的所有消息都进入同一分区。这是最简单和最常用的方法。这与用于蜂巢分桶的方法相同。它使用模运算进行散列。
Hash(Key) % 分区数 -> 分区号
可以说,这里的key将有助于定义生产者想要始终发送消息的分区以保持顺序。但是,这种方法的缺点是它使用随机哈希值将数据拉到指定的分区,并且它遵循将数据重载到单个分区。但是,这种方法的缺点是因为它使用随机哈希值将数据拉到指定的分区,并且它遵循将数据重载到单个分区。

自定义分区程序
我们可以编写自己的业务逻辑来决定哪些消息需要发送到哪个分区。通过这种方法,我们可以根据业务逻辑对消息进行排序,同时实现并行性。

如需了解更多详情,请查看下方内容

https://medium.com/latentview-data-services/how-to-use-apache-kafka-to-guarantee-message-ordering-ac2d00da6c22

另请注意,此信息表示分区级并行度

有一种新的并行策略也称为消费者级并行。我还没有读过它,但你可以在下面的汇合处找到详细信息link

https://www.confluent.io/blog/introducing-confluent-parallel-message-processing-client/