共计 1289 个字符,预计需要花费 4 分钟才能阅读完成。
要想实现音讯有序,须要从 Producer 和 Consumer 两方面来思考。
首先,Producer 生产音讯的时候就必须要有序。
而后,Consumer 生产的时候,也要按程序来,不能乱。
Producer 有序
像 RabbitMQ 这类一般的音讯零碎,队列构造简略,Producer 向队列中发送音讯就完了,进入队列的音讯必定是有序的。
Kafka 比拟非凡,因为它的一个 Topic(就是队列的概念)实际上分为了多个 Partition。
Producer 发送音讯的时候,是扩散在不同 Partition 的。
Producer 按程序发消息,但进入 Kafka Topic 之后,这些音讯就不肯定进到哪个 Partition 了,所以程序必定是乱的。
如果想 Topic 内的音讯 全局有序,就只能设置一个 Partition 了,这就变成了 RabbitMQ 那种构造。
但这种构造不合乎 Kafka 的设计理念,Topic 只有一个 Partition 就失去了扩展性。
kafka 还反对一种 部分有序 的形式,就是把某一类的音讯都放入同一个 Partition,就保障了这组音讯的程序。
在发消息的时候指定 Partition Key,Kafka 对其进行 Hash 计算,依据计算结果决定放入哪个 Partition。
所以,Partition Key 一样的音讯必定是在一起的。
例如应用用户 ID 做 key,这样同一个用户的音讯必定是在一起的,就保障了这一组的音讯的有序。
Consumer 有序
MQ 内音讯有序,那么 Consumer 天然也是按程序接管的。
然而,如果应用了多个 Consumer,就可能呈现乱序。
例如 RabbitMQ 的一个 Queue 有 3 个 Consumer,尽管会按程序接管到音讯,然而它们各自的处理速度是不同的,所以,进去的后果很可能是乱序的。
如果想严格按程序来,就只能应用一个 Consumer。
如果能够应用部分有序,那么就把之前的一个队列拆为多个队列,就像 Kafka 的 Partition Key 一样,把同组数据放入同一个队列。
Kafka 中一个 Partition 只能对应一个 Consumer,但如果 Consumer 应用了多线程,就和多个 Consumer 一个成果了,还是会造成乱序。
这样的话就须要 进一步细化 音讯的分组。
为每个线程创立一个内存队列,Consumer 收到音讯后,把同组的音讯都放在同一个内存队列,由同一个线程解决即可。
小结一下,音讯的有序须要 Producer 和 Consumer 都有序。
RabbitMQ 的队列构造简略,Producer 发送的音讯是有序的。但 Kafka 非凡,一个 Topic 有多个 Partition,如果要求全局有序,就只能应用一个 Partition。
如果能够承受部分有序,就能够为音讯设置 Partition Key,其 Hash 计算结果雷同的音讯都会在同一个 Partition。
Consumer 生产时须要留神多 Consumer 的状况,例如多个生产线程。
能够在 Consumer 收到音讯后再细化分组,同组的音讯交给同一个生产线程解决。
举荐浏览
OAuth2 图解
轻松了解 Kubernetes 的外围概念
开发者必须要理解的架构技术趋势:Service Mesh