[51CTO传媒TB]注意了!Kafka与RabbitMQ千万不要乱用…( 四 )


如果消费者阻塞在重试一个消息上 , 那么底部分区的消息就不会被处理 。
获胜者:RabbitMQ是获胜者 , 因为它提供了一个解决这个问题的开箱即用的机制 。
伸缩
有多个基准测试 , 用于检查RabbitMQ和Kafka的性能 。
尽管通用的基准测试对一些特定的情况会有限制 , 但是Kafka通常被认为比RabbitMQ有更优越的性能 。
Kafka使用顺序磁盘I/O来提高性能 。 从Kafka使用分区的架构上看 , 它在横向扩展上会优于RabbitMQ , 当然RabbitMQ在纵向扩展上会有更多的优势 。
Kafka的大规模部署通常每秒可以处理数十万条消息 , 甚至每秒百万级别的消息 。
过去 , Pivotal记录了一个Kafka集群每秒处理一百万条消息[2]的例子;但是 , 它是在一个有着30个节点集群上做的 , 并且这些消息负载被优化分散到多个队列和交换器上 。
典型的RabbitMQ部署包含3到7个节点的集群 , 并且这些集群也不需要把负载分散到不同的队列上 。 这些典型的集群通常可以预期每秒处理几万条消息 。
获胜者:尽管这两个消息平台都可以处理大规模负载 , 但是Kafka在伸缩方面更优并且能够获得比RabbitMQ更高的吞吐量 , 因此这局Kafka获胜 。
但是 , 值得注意的是大部分系统都还没有达到这些极限!所以 , 除非你正在构建下一个非常受欢迎的百万级用户软件系统 , 否则你不需要太关心伸缩性问题 , 毕竟这两个消息平台都可以工作的很好 。
消费者复杂度
RabbitMQ使用的是智能代理和傻瓜式消费者模式 。 消费者注册到消费者队列 , 然后RabbitMQ把传进来的消息推送给消费者 。 RabbitMQ也有拉取(pull)API;不过 , 一般很少被使用 。
RabbitMQ管理消息的分发以及队列上消息的移除(也可能转移到DLX) 。 消费者不需要考虑这块 。
根据RabbitMQ结构的设计 , 当负载增加的时候 , 一个队列上的消费者组可以有效的从仅仅一个消费者扩展到多个消费者 , 并且不需要对系统做任何的改变 。
[51CTO传媒TB]注意了!Kafka与RabbitMQ千万不要乱用…
文章图片
RabbitMQ高效的伸缩
相反 , Kafka使用的是傻瓜式代理和智能消费者模式 。 消费者组中的消费者需要协调他们之间的主题分区租约(以便一个具体的分区只由消费者组中一个消费者监听) 。
消费者也需要去管理和存储他们分区偏移索引 。 幸运的是KafkaSDK已经为我们封装了 , 所以我们不需要自己管理 。
另外 , 当我们有一个低负载时 , 单个消费者需要处理并且并行的管理多个分区 , 这在消费者端会消耗更多的资源 。
当然 , 随着负载增加 , 我们只需要伸缩消费者组使其消费者的数量等于主题中分区的数量 。 这就需要我们配置Kafka增加额外的分区 。
但是 , 随着负载再次降低 , 我们不能移除我们之前增加的分区 , 这需要给消费者增加更多的工作量 。
尽管这样 , 但是正如我们上面提到过 , KafkaSDK已经帮我们做了这个额外的工作 。
[51CTO传媒TB]注意了!Kafka与RabbitMQ千万不要乱用…
文章图片
Kafka分区没法移除 , 向下伸缩后消费者会做更多的工作
获胜者:根据设计 , RabbitMQ就是为了傻瓜式消费者而构建的 。 所以这轮RabbitMQ获胜 。
如何选择?
现在我们就如面对百万美元问题一样:“什么时候使用RabbitMQ以及什么时候使用Kafka?”概括上面的差异 , 我们不难得出以下结论:
优先选择RabbitMQ的条件:
高级灵活的路由规则
消息时序控制(控制消息过期或者消息延迟)
高级的容错处理能力 , 在消费者更有可能处理消息不成功的情景中(瞬时或者持久)
更简单的消费者实现
优先选择Kafka的条件:
严格的消息顺序
延长消息留存时间 , 包括过去消息重放的可能