Redis、Kafka 与 RabbitMQ 对比


当为微服务使用异步通信时,通常使用消息代理。代理确保不同微服务之间的通信可靠和稳定,消息在系统内得到管理和监控,并且消息不会丢失。您可以选择一些消息代理,它们的规模和数据功能各不相同。

这篇博文将比较三种最流行的代理:RabbitMQ、Kafka 和 Redis。

微服务通信:同步和异步
微服务之间有两种常见的通信方式:同步和异步。在同步通信中,调用方在发送下一条消息之前等待响应,它作为 HTTP 之上的 REST 协议运行。相反,在异步通信中,消息在不等待响应的情况下发送。这适用于分布式系统,通常需要消息代理来管理消息。

您选择的通信类型应考虑不同的参数,例如微服务的结构方式、现有的基础设施、延迟、规模、依赖关系和通信目的。异步通信的建立可能更复杂,并且需要向堆栈中添加更多组件,但是为微服务使用异步通信的优势大于劣势。

异步通信优势
首先,根据定义,异步通信是非阻塞的。它还支持比同步操作更好的缩放。第三,在微服务崩溃的情况下,异步通信机制提供了各种恢复技术,通常可以更好地处理与崩溃有关的错误。此外,当使用代理而不是 REST 协议时,接收通信的服务实际上不需要相互了解。甚至可以在旧服务运行了很长时间后引入新服务,即更好地解耦服务。

最后,当选择异步操作时,你会增加你的能力,在未来创建一个中央发现、监控、负载平衡,甚至是政策执行者。这将为你的代码和系统建设提供灵活性、可扩展性和更多能力。

选择合适的消息代理
异步通信通常通过消息代理进行管理。还有其他方法,例如 aysncio,但它们更加稀缺和有限。
在选择用于执行异步操作的代理时,您应该考虑以下几点:

  1. Broker Scale——系统中每秒发送的消息数。
  2. 数据持久性——恢复消息的能力。
  3. 消费者能力——经纪人是否有能力管理一对一和/或一对多消费者。

一对一


一对多

比较不同的消息代理

RabbitMQ(AMQP)
规模:基于配置和资源,这里的大概是每秒 50K msg 左右。
持久性:支持持久性和瞬态消息。

一对一消费者与一对多消费者:两者都有。 RabbitMQ 于 2007 年发布,是最早创建的通用消息代理之一。它是一个开放源代码,通过实施高级消息队列协议 (AMQP) 通过点对点和发布-订阅方法传递消息。它旨在支持复杂的路由逻辑。

有一些托管服务允许您将其用作 SaaS,但它不是本地主要云提供商堆栈的一部分。RabbitMQ 支持所有主要语言,包括 Python、Java、.NET、PHP、Ruby、JavaScript、Go、Swift 等。

在持久模式下会出现一些性能问题。


Kafka
规模:每秒最多可以发送一百万条消息。
持久性:是的。

一对一消费者与一对多消费者:只有一对多(乍一看似乎很奇怪,对吧?!)。

Kafka 由 Linkedin 于 2011 年创建,用于处理高吞吐量、低延迟的处理。作为一个分布式流媒体平台,Kafka 复制了一个发布-订阅服务。它提供数据持久性并存储记录流,使其能够交换高质量的消息。

Kafka 在 Azure、AWS 和 Confluent 上管理 SaaS。他们都是Kafka项目的创造者和主要贡献者。Kafka 支持所有主要语言,包括 Python、Java、C/C++、Clojure、.NET、PHP、Ruby、JavaScript、Go、Swift 等。

Redis
规模:每秒最多可以发送一百万条消息。
持久性:基本上,不——它是一个内存数据存储。
一对一消费者与一对多消费者:两者都有。

Redis 与其他消息代理有点不同。Redis 的核心是一个内存数据存储,可用作高性能键值存储或消息代理。另一个区别是 Redis 没有持久性,而是将其内存转储到磁盘/数据库中。它也非常适合实时数据处理。

Redis本来就不是一对一和一对多的。然而,自从 Redis 5.0 引入了 pub-sub 之后,功能得到了提升,一对多成为了一个真正的选择。

每个用例的消息代理
我们介绍了 RabbitMQ、Kafka 和 Redis 的一些特性。这三者都是同类中的野兽,但正如所描述的那样,它们的运作方式却大不相同。以下是我们根据不同用例推荐使用正确消息代理的建议。

短消息:Redis
Redis 的内存数据库几乎非常适合不需要持久性的短消息用例。因为它提供了极快的服务和内存中功能,Redis 是持久性不是那么重要并且您可以容忍一些丢失的短期保留消息的理想选择。随着 Redis 流在 5.0 中的发布,它也是一对多用例的候选者,由于限制和旧的 pub-sub 功能,这绝对是必需的。

海量数据:Kafka
Kafka 是一个高吞吐量的分布式队列,专为长时间存储大量数据而构建。Kafka 非常适合需要持久性的一对多用例。

复杂路由:RabbitMQ
RabbitMQ 是一个较老但成熟的代理,具有许多支持复杂路由的特性和功能。在要求速率不高(大于几万msg/sec)的情况下,它甚至会支持复杂的路由通信。

考虑您的软件堆栈
当然,最后要考虑的是您当前的软件堆栈。如果您正在寻找一个相对简单的集成过程并且您不想在一个堆栈中维护不同的代理,您可能更倾向于使用您的堆栈已经支持的代理。