您如何处理消息队列中乱序的消息?

时间:2019-10-21 01:33:44

标签: apache-kafka message-queue distributed-computing distributed-system

在一次采访中,有人问我如何处理消息队列中乱序的消息。已经有一段时间了,我还没有找到确切的答案,我想知道该领域的专家是否可以帮助我回答这个问题,以解决自己的好奇心。

我了解到某些消息队列仅提供一次和FIFO保证。我也知道流系统中事件时间和处理时间的概念。例如,在基于日志的消息队列(如Kafka)中,由于存在偏移量和消息持久性,混合排序的可能性较小(我可能错了)。我还考虑过使用时间戳,要求每个消息发件人在发送之前记录消息的时间,但是由于时钟偏斜,这会造成不一致。

鉴于所有这些,我想知道一个地址如何在传统的消息传递系统(例如AMQP,JMS或RabbitMQ)中混合排序,在该系统中可能有十几个IOT设备正在发送消息,而我作为消费者想在它们中协调它们。正确的顺序。

2 个答案:

答案 0 :(得分:1)

我可以回答有关Apache Kafka的问题。 Apache Kafka通过分区保证主题上的严格顺序,这意味着每个分区都是按严格顺序附加的不可变消息序列。 因此,如果一个以上的分区使用者可能会使用来自多个分区的消息,而这些消息不能严格按照顺序进行。我们可以考虑使用以下2个选项来实现严格的顺序。

  1. 如果要查找1个生产者生产者消息,则每个主题仅使用1个分区。因此,生产者将按顺序在同一分区上发布,这将使消费者按严格的顺序进行消费。

enter image description here

  1. 生产者将消息发布到多个分区,因此在消费者组中使用多个消费者,但使用分配给每个消费者的特定分区来消费来自特定分区的消息将保证每个消费者每个分区的严格订购

enter image description here

答案 1 :(得分:1)

如果您的系统正在使用队列,则提供有序消息保证,然后只需使用该通道即可(例如kakfa的单个分区,在某些设置下为AMQP)。 但是,如果您的系统正在使用的队列不提供严格排序,则通常的想法是,客户端可以随发送的每封邮件单调增加[1]个数字(或时间戳)排队。这构成了生产者打算发送给接收者的顺序的基础。

如何单调增加价值:

使用时间戳记: 带有CLOCK_MONOTONIC [2]的POSIX clock_gettime()函数提供了获得单调递增时间戳的选项,生产者可以使用该时间戳为每条消息添加时间戳。当接收者看到接收到的消息的时间戳早于最新消息时,可以识别出乱序的消息。

使用序列号: 在发送每条消息之前,您可以简单地增加一个原子计数器并将计数器值附加到每条消息上,以便接收者可以知道预期的顺序。这将形成严格增加的顺序。该方法与Lamport的逻辑时钟[3]非常相似,后者为生产者提供了虚拟时钟。

在接收方处理乱序消息: 这几乎是特定于应用程序的,但是通常,当消息乱序到达时,您有两个选择: a)丢弃旧消息,例如在接收者必须显示股票的最新价值的情况下。 b)具有缓冲区以对排序进行重新排序,例如在TCP连接中(例如zookeeper使用TCP作为FIFO排序队列[4-5])

工具: 如果您不为消息添加时间戳,则将所有消息按顺序从生产者发送到Apache kafka 分区 ,因为这将确保接收者可以按顺序接收消息。 / p>

如果您使用的消息传递系统不能保证有序交付(例如某些设置下的AMQP [6]),则可以考虑为每条消息添加其他单调递增的数字/时钟。

[1] https://en.wiktionary.org/wiki/monotonic_increasing#targetText=Adjective,contrast%20this%20with%20strictly%20increasing

[2] https://linux.die.net/man/2/clock_gettime

[3] https://en.wikipedia.org/wiki/Lamport_timestamps#Lamport的s_logical_clock_in_distributed_systems

[4] https://cwiki.apache.org/confluence/download/attachments/24193445/zookeeper-internals.pdf?version=1&modificationDate=1295034038000&api=v2

[5] http://www.tcs.hut.fi/Studies/T-79.5001/reports/2012-deSouzaMedeiros.pdf

[6] RabbitMQ - Message order of delivery