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

Raj*_*R.G 44 apache-kafka

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

Vis*_*ohn 69

在Kafka中,并行性等于主题的分区数.

例如,假设您的消息是基于user_id进行分区的,并考虑具有user_ids 1,2,3和4的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的设计方式.

  • 是的,@约翰.但在上述情况下,无法保证将以正在发送的相同顺序接收消息.我指的是这个,http://stackoverflow.com/questions/21293937/apache-kafka-message-consumption-when-partitions-outnumber-consumers (2认同)
  • @ RajanR.GI认为您应该在生成消息时正确地对消息进行分区.例如,您可以按user_id进行分区,然后特定user_id的消息将到达特定分区(始终相同),从而保证该user_id的所有消息都保持有序.您不需要在不同的user_ids之间保留顺序,对吧? (2认同)

ser*_*jja 23

我决定将我的评论移到一个单独的答案,因为我认为这样做是有意义的.

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

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

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


小智 8

在kafka中,来自同一生产者的具有相同密钥的消息将按顺序传递给消费者

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

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

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