跳转到主要内容
Chinese, Simplified

人类如何做决定?在日常生活中,情感往往是触发一个复杂或压倒性决定的断路器因素。但是,专家们做出的复杂决定会带来长期后果,这不能纯粹是一时冲动。高绩效者通常只有在他们的专家、潜意识已经吸收了做决定所需的所有事实之后,才会使用“本能”、“直觉”或其他情感的断路器。

今天,市场上有几十种消息传递技术、无数esb和将近100家iPaaS供应商。自然,这就产生了如何根据您的需要选择正确的消息传递技术的问题——特别是对于那些已经在特定选择上进行了投资的技术。我们是否要大规模地转换?只是用合适的工具做合适的工作?我们是否正确地为业务需求制定了手头的工作?考虑到这一点,什么才是适合我的工具呢?更糟糕的是,详尽的市场分析可能永远不会结束,但考虑到集成代码的平均寿命,尽职调查至关重要。

这篇文章让那些无意识的专家们开始考虑一些治疗方法,从最现代、最流行的选择开始:RabbitMQ和Apache Kafka。每个都有自己的起源故事、设计意图、使用案例、集成能力和开发经验。起源揭示了任何一款软件的总体设计意图,是一个很好的起点。但是需要注意的是,在本文中,我的目标是围绕message broker重叠的用例比较这两个用例,而不是Kafka现在擅长的“事件存储/事件来源”用例。

起源

RabbitMQ是一种实现各种消息传递协议的“传统”消息代理。它是第一批实现合理级别的特性、客户机库、开发工具和高质量文档的开放源码消息代理之一。RabbitMQ最初是为了实现AMQP而开发的,AMQP是一种具有强大路由特性的消息传递开放线协议。虽然Java有JMS这样的消息传递标准,但它对需要分布式消息传递的非Java应用程序没有帮助,因为分布式消息传递严重限制了任何集成场景(微服务或单片集成)。随着AMQP的出现,对于开源消息代理来说,跨语言的灵活性变得真实了。

Apache Kafka是用Scala开发的,最初是在LinkedIn作为连接不同内部系统的一种方式。当时,LinkedIn正在转向一个更加分布式的架构,需要重新设想数据集成和实时流处理等功能,摆脱以前解决这些问题的单一方法。Kafka今天在Apache软件基金会的产品生态系统中得到了很好的采用,并且在事件驱动的架构中特别有用。

架构和设计

RabbitMQ被设计成一个通用消息代理,它采用了点对点、请求/应答和发布-子通信样式模式的几种变体。它使用智能代理/哑消费者模型,专注于以与代理跟踪消费者状态大致相同的速度向消费者交付消息。它很成熟,在正确配置的情况下性能很好,得到了很好的支持(客户端库Java、. net、node)。js, Ruby, PHP和更多的语言),并且有几十个插件可以扩展到更多的用例和集成场景。

图1 -简化的RabbitMQ整体架构来源:http://kth.diva-portal.org/smash/get/diva2:813137 FULLTEXT01.pdf

根据需要,RabbitMQ中的通信可以是同步的,也可以是异步的。发布者向交换器发送消息,使用者从队列中检索消息。通过交换器将生产者从队列中解耦,可以确保生产者不必为硬编码的路由决策所累。RabbitMQ还提供了许多分布式部署场景(并要求所有节点都能够解析主机名)。可以将多节点集群设置为集群联合,并且不依赖于外部服务(但是一些集群形成插件可以使用AWS api、DNS、领事、etcd)。

Apache Kafka是为高容量发布-订阅消息和流而设计的,这意味着它是持久的、快速的和可伸缩的。从本质上讲,Kafka提供了一种持久的消息存储,类似于日志,运行在服务器集群中,以称为主题的类别存储记录流。

图2 -全局Apache Kafka架构(1个主题,1个分区,复制因子4)

每个消息由一个键、一个值和一个时间戳组成。与RabbitMQ几乎相反的是,Kafka雇佣了一个愚蠢的经纪人,并使用聪明的消费者来读取它的缓冲区。Kafka不尝试跟踪每个消费者读了哪些消息,只保留未读的消息;相反,Kafka将所有消息保留一段时间,使用者负责跟踪它们在每个日志中的位置(使用者状态)。因此,有了合适的开发人才来创建消费者代码,Kafka就可以支持大量的消费者,并以很少的开销保留大量的数据。正如上面的图表所示,Kafka确实需要外部服务来运行——在这个例子中是Apache Zookeeper,通常认为理解、设置和操作这些服务并不简单。

需求和用例

许多开发人员开始研究消息传递,是因为他们意识到必须将许多东西连接在一起,而共享数据库等其他集成模式不可行或太危险。

Apache Kafka包含了代理本身,这实际上是其中最著名和最流行的部分,并针对流处理场景进行了设计和营销。除此之外,Apache Kafka最近还添加了Kafka Streams,它将自己定位为流媒体平台的替代品,如Apache Spark、Apache Flink、Apache Beam/谷歌云数据流和Spring云数据流。文档很好地讨论了流行的用例,如网站活动跟踪、度量、日志聚合、流处理、事件来源和提交日志。它描述的其中一个用例是消息传递,这可能会产生一些混乱。因此,让我们来解包一点,得到一些明确的消息传递场景是最适合Kafka的,例如:

  • 流从A流到B流,无需复杂的路由,最大吞吐量(100k/sec+),至少按分区顺序发送一次。
  • 当您的应用程序需要访问流历史记录时,至少按分区顺序交付一次。Kafka是一个持久的消息存储,客户端可以根据需要获得事件流的“重播”,这与更传统的消息代理不同,后者一旦消息被发送,就会从队列中删除。
  • 流处理
  • 事件溯源

RabbitMQ是一种通用的消息传递解决方案,通常用于允许web服务器快速响应请求,而不是在用户等待结果时被迫执行大量资源的过程。它还适合将消息分发给多个收件人,以便在高负载(20k+/秒)情况下在工作人员之间平衡负载。当您的需求超出吞吐量时,RabbitMQ可以提供很多功能:可靠交付、路由、联合、HA、安全、管理工具和其他功能。让我们检查一些场景最好的RabbitMQ,如:

  • 您的应用程序需要使用现有协议的任何组合,如AMQP 0-9-1、STOMP、MQTT、AMQP 1.0。
  • 您需要对每条消息(死信队列等)进行更细粒度的一致性控制/保证。然而,Kafka最近为事务添加了更好的支持。
  • 您的应用程序需要点到点、请求/应答和发布/订阅消息传递方面的多样性
  • 对消费者的复杂路由,集成多个具有重要路由逻辑的服务/应用程序

RabbitMQ也可以有效地解决卡夫卡的几个强大的使用案例,但在附加软件的帮助下。当应用程序需要访问流历史记录时,RabbitMQ通常与Apache Cassandra一起使用,或者与LevelDB插件一起用于需要“无限”队列的应用,但这两个特性都不是与RabbitMQ一起发布的。

想要更深入地了解微服务——Kafka和RabbitMQ的特定用例,请访问关键博客并阅读Fred Melo的这篇短文

开发人员的经验

RabbitMQ正式支持Java, Spring,。net, PHP, Python, Ruby, JavaScript, Go, Elixir, Objective-C, Swift -通过社区插件与许多其他客户端和devtools。RabbitMQ客户端库是成熟的,并且有良好的文档记录。

Apache Kafka在这个领域已经取得了很大的进步,虽然它只提供Java客户端,但是社区开源客户端、生态系统项目以及适配器SDK都在不断增长,允许您构建自己的系统集成。大部分配置都是通过.properties文件或编程方式完成的。

这两种选择的流行对许多其他软件供应商有强烈的影响,他们确保RabbitMQ和Kafka与他们的技术很好地工作。

至于开发者的体验…值得一提的是我们在Spring Kafka、Spring Cloud Stream等中提供的支持。

安全与操作

这两者都是RabbitMQ的优势。RabbitMQ管理插件提供了一个HTTP API,一个基于浏览器的管理和监控UI,以及针对操作人员的CLI工具。长期监视数据存储需要像CollectD、Datadog或New Relic这样的外部工具。RabbitMQ还提供了用于监控、审计和应用程序故障排除的API和工具。除了支持TLS之外,RabbitMQ附带了由内置数据存储、LDAP或外部基于http的提供者支持的RBAC,并支持使用x509证书而不是用户名/密码对进行身份验证。使用插件可以相当直接地开发其他身份验证方法。

这些领域对Apache Kafka提出了挑战。在安全方面,最近的Kafka 0.9版本增加了TLS、基于JAAS角色的访问控制和kerberos/plain/scram认证,使用CLI来管理安全策略。这对以前的版本有很大的改进,以前的版本只能在网络级别锁定访问,这在共享或多租户方面不太好用。

Kafka使用由shell脚本、属性文件和特定格式的JSON文件组成的管理CLI。Kafka经纪人、生产者和消费者通过Yammer/JMX发布指标,但不维护任何历史,这实际上意味着使用第三方监控系统。使用这些工具,操作能够管理分区和主题,检查消费者偏移位置,并使用Apache Zookeeper为Kafka提供的HA和FT功能。虽然许多人对Zookeeper的需求持高度怀疑态度,但它确实为Kafka用户带来了集群的好处。

例如,一个3节点的Kafka集群即使在出现2次故障后仍然可以正常工作。然而,如果你想在Zookeeper中支持同样多的失败,你需要额外的5个Zookeeper节点,因为Zookeeper是基于quorum的系统,只能容忍N/2+1个失败。这些显然不应该与Kafka节点位于同一位置——所以要建立一个3节点的Kafka系统,你需要~ 8台服务器。在考虑Kafka系统的可用性时,操作人员必须考虑ZK集群的属性,包括资源消耗和设计。

性能

Kafka在这里的亮点在于设计:100k/秒的性能通常是人们选择Apache Kafka的关键驱动因素。

当然,要描述和量化每秒消息率是很棘手的,因为它们很大程度上取决于您的环境和硬件、工作负载的性质、使用哪种交付保证(例如,持久的代价是昂贵的,镜像的代价更大),等等。

每秒发送20K条消息很容易通过单只RabbitMQ,实际上,超过20K条消息并不难,因为保证的要求并不多。队列是由一个Erlang轻量级线程获得合作计划在一个本地操作系统线程池,所以它变成了一个自然瓶颈或瓶颈作为一个单独的队列是永远不会做更多的工作比CPU周期工作。

提高每秒的消息量通常要合理利用环境中的并行性,比如通过巧妙的路由来中断跨多个队列的流量(以便不同队列可以并发运行)。当RabbitMQ达到每秒100万条消息时,这个用例基本上是完全明智地做到这一点——但是实现时使用了大量资源,大约30个RabbitMQ节点。大多数RabbitMQ用户在使用由3到7个RabbitMQ节点组成的集群时都可以享受卓越的性能。

 

原文:https://tanzu.vmware.com/content/blog/understanding-when-to-use-rabbitmq-or-apache-kafka

本文:http://jiagoushi.pro/node/1188

讨论:请加入知识星球【首席架构师圈】或者加小号【jiagoushi_pro】或者QQ群【11107777】

 

Tags
 
Article
知识星球
 
微信公众号
 
视频号