【问题标题】:Is RabbitMQ or Kafka message queue a 1:1 messaging system?RabbitMQ 或 Kafka 消息队列是 1:1 消息系统吗?
【发布时间】:2020-09-12 16:57:21
【问题描述】:

正如answer中提到的,

消息队列是单向管道:一个进程写入队列,另一个进程按顺序读取数据

SysV 消息队列就是一个例子


所以,我的理解是,

一个消息队列被两个进程使用,一个进程(生产者)在队列中插入一个项目,另一个进程(消费者)从队列中消费该项目


1) RabbitMQ 或 Kafka 消息队列是 1:1 消息系统吗? 两个进程使用,一个进程写入,另一个进程读取......

2) 消费者消费完商品后,商品是否会被删除?如果不是,为什么我们需要队列数据结构?为什么不只是共享内存?

【问题讨论】:

  • Kafka 存储不可变的记录日志,这些记录由称为生产者的进程写入并由称为消费者的进程读取。这非常符合你的定义。我以前从未听说过将 1:1 消息传递系统用作术语,但在 Kafka 的情况下,一条记录只能被写入一次,但可以被许多不同的消费者读取多次,而这些消费者彼此之间不需要任何了解。这是使它与rabbitmq有些不同的一个方面。
  • @dawsaw 说有 10 个消费者,那么,你的意思是,Kafka 消息队列中的一个元素在 10 个消费者全部消费之前不会被删除?它是如何工作的?
  • 在代理(服务器端)根据保留策略(可能基于时间或大小)删除它之前,它不会被删除。消费者对何时从队列中删除记录没有任何发言权,这一切都在代理本身上完成。我相信这是与rabbitmq等传统消息队列的关键区别
  • @dawsaw 那么,当项目没有被删除时,维护队列有什么意义呢?为什么不只维护一些地图或共享内存?

标签: java apache-kafka rabbitmq ipc message-queue


【解决方案1】:

Kafka 并不是严格的 1:1 消息传递系统。多个生产者可以写入一个主题,多个消费者可以从中读取。此外,在 Kafka 中,可以为多个消费者分配相同或不同的消费者组。每条消息只被每个消费者组中的一个消费者消费(负载平衡),所有消费者组都会收到每条消息的副本(当然,如果他们订阅了相应的主题并且没有消息丢失)。这篇文章很好地描述了这个过程:Scalability of Kafka Messaging using Consumer Groups

在 Kafka 中,所有消息都保存在磁盘上并存储,直到 compaction 获取它,或 retention.ms 通过,或超过日志大小。这是一个非常高级的观点,这里有很多细微差别。比如:消息存储在段中,每个段包含多条消息。当一条消息的保留期过去时,它不会从该段中删除,而是 Kafka 等到该段中的所有消息都过期并立即删除整个段。此外,保留可能在日志超过最大大小之前出现,反之亦然:日志甚至在保留期过去之前就可能超过大小。等等。只需阅读docs 并关注有关“日志清理器”和“保留”的主题。

在 Kafka 消费者读取消息后,它既不会被压缩,也不会过期。因此,它不会从日志中删除并保留在那里。这也意味着消费者可以在需要时重新读取每条消息(直到它被完全删除)。如果您的一些消费者由于某种原因离线并且无法在消息进入时对其进行处理,这可能会很有用。它还允许交易重播等有趣的功能。持久性是 Kafka 的特性之一。

共享内存?好吧,严格来说,共享内存只允许在单个进程中使用。因此,当您需要从不同的进程访问它时,您通常不能使用“共享内存”。当您的应用程序在多个主机上运行时,绝对没有办法拥有“共享内存”。但是,有内存中的代理。就像 Redis 可以用作消息代理一样,它都是在内存中的。但是,如果这样的代理由于某种原因重新启动,您将失去一切。说到 Redis:它有 two persistence configurations 专门用于处理重启。

我不确定 RabbitMQ,但它可能会在消费者默认确认消息后删除消息。所以它更接近于 1:1 的心理模型。但是,RabbitMQ employs 磁盘持久化也是如此。

【讨论】:

猜你喜欢
  • 2011-01-18
  • 2013-08-09
  • 2020-03-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-28
  • 2012-12-06
  • 1970-01-01
相关资源
最近更新 更多