admin管理员组

文章数量:1642350

1.背景

在Kafka中Partition(分区)是真正保存消息的地方,发送的消息都存放在这里。Partition(分区)又存在于Topic(主题)中,并且一个Topic(主题)可以指定多个Partition(分区)。
在Kafka中,只保证Partition(分区)内有序,不保证Topic所有分区都是有序的

2.解决方案

  • 一个 topic,一个 partition,一个 consumer,内部单线程消费,单线程吞吐量太低,不建议使用
  • 生产者在发送消息的时候指定要发送到特定Partition(分区)
    将 producer 发送的数据封装成一个 ProducerRecord 对象。
    (1)指明 partition 的情况下,直接将指明的值直接作为 partiton 值;
    (2)没有指明 partition 值但有 key 的情况下,在Producer往Kafka插入数据时,控制同一Key分发到同一Partition,并且设置参数max.in.flight.requests.per.connection=1,也即同一个链接只能发送一条消息,如此便可严格保证Kafka消息的顺序

3.场景说明

3.1场景

建了一个 topic,有三个 partition。生产者在写的时候,指定一个 key,比如说指定了某个订单 id 作为 key,那么这个订单相关的数据,一定会被分发到同一个 partition 中去,而且这个 partition 中的数据一定是有顺序的。
消费者从 partition 中取出来数据的时候,也一定是有顺序的。到这里,顺序还是 ok 的,没有错乱。但是,如果在消费者里可能会搞多个线程来并发处理消息。因为如果消费者是单线程消费处理,而处理比较耗时的话,比如处理一条消息耗时几十 ms,那么 1 秒钟只能处理几十条消息,这吞吐量太低了。而多线程并发跑的话,顺序可能就会乱掉。
如图

3.2 解决方案

消费者可以 N 个内存队列,具有相同 key 的数据都到同一个内存队列;然后对于 N 个线程,每个线程分别消费一个内存队列 即可,这样就能保证顺序性。
如图

本文标签: 顺序消息Kafka