具有多个分区的Apache Kafka消息顺序

时间:2015-04-23 10:14:17

标签: apache-kafka

根据Apache Kafka文档,可以在分区或主题中的一个分区中实现消息的顺序。在这种情况下,我们得到的并行性好处是什么,它等同于传统的MQ,不是吗?

6 个答案:

答案 0 :(得分:64)

在Kafka中,并行度等于主题的分区数。

例如,假设您的邮件是基于user_id进行分区的,并考虑4条包含user_ids 1,2,3和4的邮件。假设您有一个包含4个分区的“用户”主题。

由于分区基于user_id,假设具有user_id 1的消息将转到分区1,具有user_id 2的消息将转到分区2,依此类推..

同时假设您有4个消费者参与该主题。由于您有4个消费者,Kafka会将每个消费者分配到一个分区。因此,在这种情况下,只要推送4条消息,消费者就会立即使用它们。

如果您有2个主题而不是4个消费者,则每个消费者将处理2个分区,消耗吞吐量几乎为一半。

要完全回答你的问题, Kafka仅对分区内的邮件提供总订单,而不是在主题中的不同分区之间。

即,如果分区2中的消耗非常慢,而部分离子4中的消耗非常快,那么带有user_id 4的消息将在使用user_id 2的消息之前消耗。这就是Kafka的设计方式。

答案 1 :(得分:21)

我决定将我的评论移到单独的答案中,因为我觉得这样做是有道理的。

虽然John对他所写的内容100%正确,但您可以考虑重新考虑您的问题。你真的需要所有的消息保持秩序吗?或者您是否需要特定user_id(或其他)的所有消息才能保持秩序?

如果是第一个,那么你可以做的就不多了,你应该使用1个分区并失去所有的并行能力。

但是如果是第二种情况,你可以考虑通过某个键对你的消息进行分区,因此该密钥的所有消息都将到达一个分区(如果你调整主题大小,它们实际上可能会转到另一个分区,但这是不同的case)因此将保证该密钥的所有消息都是有序的。

答案 2 :(得分:7)

在kafka中,来自同一制作人的相同密钥的消息将按顺序发送给消费者

另一件事是,分区中的数据将按其编写顺序存储,因此,将从分区读取的数据将按顺序读取

因此,如果您希望跨多个分区按顺序获取消息,那么您确实需要使用密钥对消息进行分组,以便具有相同密钥的消息转到同一分区,并且在该分区中消息是排序。

简而言之,您需要在逻辑上设计一个类似上面的两级解决方案,以便在多分区中获取消息。

答案 3 :(得分:0)

您可以考虑在源处创建数据集时具有时间戳/日期的字段。

一旦消耗了数据,您就可以将数据加载到数据库中。在将数据集用于任何用例之前,需要在数据库级别对数据进行排序。嗯,这是一种帮助你以多种方式思考的尝试。

我们假设我们有一个消息密钥作为在创建数据时生成的时间戳,该值是实际的消息字符串。

当消费者接收到消息时,消息将写入HBase,RowKey为kafka密钥,值为kafka值。

因为,HBase是一个带有时间戳的有序映射,因为键会自动按顺序对数据进行排序。然后,您可以为HBase提供下游应用程序的数据。

通过这种方式,你不会失去卡夫卡的平行性。您还有权处理数据库级别的数据排序和执行多个处理逻辑。

注意:任何分布式消息代理都不保证整体订购。如果您坚持这样做,您可能需要重新考虑使用其他消息代理,或者您需要在kafka中使用单个分区,这不是一个好主意。 Kafka通过增加分区或增加消费者群体来实现并行性。

答案 4 :(得分:0)

传统MQ的工作方式是,一旦处理完消息,就会从队列中删除它。消息队列允许一群订阅者从队列末尾提取消息或一批消息。队列通常在关闭消息时允许某种级别的事务,以确保在消息被删除之前执行了所需的操作,但是一旦处理了消息,它就会从队列中删除。

另一方面,使用Kafka,您可以将消息/事件发布到主题,并且它们会被持久化。当消费者收到它们时,它们不会被删除。这允许您重放消息,但更重要的是,它允许大量消费者基于相同的消息/事件处理逻辑。

您仍然可以扩展以在同一个域中进行并行处理,但更重要的是,您可以添加基于同一事件执行不同逻辑的不同类型的使用者。换句话说,使用Kafka,您可以采用响应式pub / sub体系结构。 参考:https://hackernoon.com/a-super-quick-comparison-between-kafka-and-message-queues-e69742d855a8

答案 5 :(得分:0)

好吧,这是一个旧话题,但仍然有意义,因此决定分享我的观点。

我认为这个问题有点令人困惑。

如果您需要对消息进行严格排序,则在使用消息时应保持相同的严格排序。在队列中排序消息绝对没有意义,但在使用消息时却没有意义。卡夫卡兼顾了两全其美。它允许从生成到消费为止的一个分区内对消息进行排序,同时允许多个分区之间的并行性。因此,如果您需要

关于一个主题发布的所有事件的绝对顺序,请使用单个分区。您将不需要并行性,也不需要并行性(再次,并行和严格排序不会一起使用)。

选择多个分区和使用者,使用一致的散列以确保所有需要按照相对顺序的消息都进入单个分区。