概述:ruby
我花了一些时间解剖各类库执行分布式消息。在这个分析中,我看了几个不一样的方面,包括API特性,易于部署和维护,以及性能质量.。消息队列已经被分为两组:brokerless和brokered。服务器
brokerless消息队列是对等的,没有中间商参与信息的传递,而brokered队列有一些服务器端点之间。网络
性能分析的一些系统: less
Brokerless
nanomsg
ZeroMQ异步
Brokered
ActiveMQ
NATS
Kafka
Kestrel
NSQ
RabbitMQ
Redis
ruby-natssocket
测试环境:分布式
首先,让咱们来看看性能指标,由于这能够说是人们最关心的。我已经测量了两个关键指标:吞吐量和延迟。性能
全部的测试都运行在一台MacBook Pro 2.6 GHz的i7处理器,16GB内存。这些测试是评估一个单一的生产者和单一消费者的发布订阅拓扑结构。这提供了一个很好的基线。这将是有趣的基准缩放拓扑结构,但须要更多的仪器。测试
吞吐量基准是指系统每秒可以处理消息的数量,须要注意的是队列中可能有没有单一的“吞吐量”。咱们在两个不一样的端点之间发送消息,因此咱们观察到的是一个“发送方”吞吐量和一个“接收方”吞吐量,即每秒能够发送的消息数和每秒能够接收的消息数.。优化
咱们此次测试经过发送1,000,000 个1kb 的消息而且计算两边发送和接收消息的时间,这里面选择1kb的数据是由于这种数据更加贴近咱们平常开发中遇到的消息请求,许多性能测试倾向于在100到500字节的范围内使用较小的消息.,尽管每一个系统都是各不相同的,咱们只可以选取大致上类似的测试数据来进行测试。对于面向消息的中间件系统,只使用一个代理。
Brokeless:
从图片咱们能够看出,在发送测有很高的吞吐量,然而有趣的是,发送者与接收者的比率差距。
ZeroMQ可以发送超过每秒5000000条消息/每秒但只能收到约600000 /秒。
相反,nanomsg发出害羞的3000000帧/秒可接待近2000000。
Brokered:
咱们能够很直观的观察到,Brokered 消息队列比Brokerless 少了至少两个数量级以上的吞吐量。有一半的Brokered 消息队列吞吐量少于25000条消息每秒。对于Redis的吞吐量或许有必定的误导,尽管Redis 提供 发布/订阅 功能,它并非真正设计为一个强大的消息队列。以相似的方式使用ZeroMq,Redis切断了慢用户,重要的是要指出,这不是可以可靠地处理这种体积的消息。咱们能够将他当作一个特殊点。Kafla 和 ruby-nats 和Redis 有类似的特色,可是可以可靠的处理间歇性故障信息。NATs 在这方面有着优越的吞吐量
经过上述的图示分析,咱们能够看到,Brokered 队列在发送和接收两方面有着一致的吞吐量,而不像Brokerless 那样,发送方与接收方的吞吐量有着较大的差别。
第二个关键性能指标是消息延迟,这就测量了在端点之间传输消息须要多长时间。直觉可能告诉咱们,这仅仅是吞吐量的逆,即若是吞吐量是消息/秒,延迟是秒/消息。然而,仔细看从ZeroMQ白皮书借这个形象,咱们能够看到,这不是个案。
现实状况是,每一个消息发送的延迟线是不统一的,它能够为每个不一样的。事实上,延迟和吞吐量之间的关系是有点涉及。
与吞吐量不一样的是,延迟的测量并不区分发送方和接收方,而是做为一个总体。可是,因为每一个消息都有本身的延迟,咱们将看看他们的平均值。进一步,咱们将看到平均消息延迟与发送的消息数有关.。直觉告诉咱们,更多的信息意味着更多的排队,这意味着更高的延迟。
下图中:
蓝色:nanomsg
红色:ZeroMq
在通常状况下,咱们的假设证实正确的,由于更多的消息被发送到系统中,每一个消息的延迟增长。有趣的是,当咱们接近1000000条消息时,延迟出现的速度变慢了500000点.。另外一个有趣的观察是在1000和5000之间的消息延迟的初始峰值,这是更加显着nanomsg。这很难肯定因果关系,可是这些变化可能反映了如何在每一个库中实现消息批处理和其余网络堆栈遍历优化.。更多的数据点能够提供更好的可视性。
咱们看一下Brokered队列和一些有趣的新的相似的模式。
ActiveMq
Kafka
RabbitMq
他们的延迟数量级高于其余的Brokered 延迟,所以他们ACtiveMq与RabbitMq分红了本身AMQP范畴。
如今,咱们已经看到了一些关于这些不一样的库如何执行的经验数据,我将看看他们如何从务实的角度来看工做。消息吞吐量和速度是很重要的,但若是库很难使用、部署或维护,则不太实用.。
从技术上讲,nanomsg不是一个消息队列,而是一个执行socket风格的图书馆分布式消息经过各类便捷的方式。所以,除了在应用程序中嵌入库自己以外,没有什么能够部署的.。这使得部署一个非问题。
Nanomsg是一个由ZeroMQ的做者写的,和我讨论过,在对库的工做以一个很是相似的方式。从发展的角度来看,nanomsg提供全面清洁的API。与ZeroMQ不一样,认为不存在一个上下文中,套接字绑定到。此外,nanomsg提供可插拔的运输和通信协议,使其更加开放的延伸。其额外的内置可扩展性协议也使它至关有吸引力。
像ZeroMQ同样,它保证消息将被原子性地传递完整和有序,但不保证它们的交付。局部的消息将没法交付,而且部分消息可能没法被交付。
ZeroMq 的研发者 Martin Sustrik:很清楚的指出:
Guaranteed delivery is a myth. Nothing is 100% guaranteed. That’s the nature of the world we live in. What we should do instead is to build an internet-like system that is resilient in face of failures and routes around damage.(保证交付是一个神话。没有100%保证。这就是咱们生活的世界的性质。咱们应该作的是创建一个互联网般的系统,面对失败和路线损坏时弹性。)
ActiveMQ 和 RabbitMQ 都是AMQP 的一种具体实现。他们扮演着一个保证当心可以正常交付的角色。AcitveMQ 和 RabbitMQ 都支持 持久性或非持久性的信息交付。默认状况下,消息会存储到磁盘中,能够保证消息队列重启时数据的一致,避免消息的丢失。它们还支持同步和异步发送消息,前者对延迟有实质性影响。为了保证交付,这些代理使用消息确认,这也致使巨大的延迟代价。
就可用性和容错性而言,这些代理经过共享存储或无共享支持集群。队列能够跨集群节点进行复制,所以没有单点故障或消息丢失。
AMQP是一个非平凡的协议,其创做者声称过分设计。这些额外的保证是以牺牲主要复杂性和性能折衷为代价的。从根本上说,客户更难实现和使用。
因为它们是消息代理,ActiveMQ和RabbitMQ是须要在分布式系统中管理的额外移动部件,这会带来部署和维护成本。
最后是Redis。虽然Redis是轻量级消息和临时存储的理想选择,但我不能主张将其用做分布式消息传递系统的主干。它的pub / sub很快,但它的功能有限。它须要大量的工做来创建一个健壮的系统。存在更好地适合于该问题的解决方案,诸如上面描述的那些解决方案,而且还存在一些缩放问题。
除此以外,Redis易于使用,易于部署和管理,而且占用空间相对较小。根据用例,它能够是一个伟大的选择实时消息
附上原博文地址:http://bravenewgeek.com/dissecting-message-queues/