概述:
我花了一些時間解剖各種庫執行分布式消息。在這個分析中,我看了幾個不同的方面,包括API特性,易於部署和維護,以及性能質量.。消息隊列已經被分為兩組:brokerless和brokered。
brokerless消息隊列是對等的,沒有中間商參與信息的傳遞,而brokered隊列有一些服務器端點之間。
性能分析的一些系統:
Brokerless
nanomsg
ZeroMQ
Brokered
ActiveMQ
NATS
Kafka
Kestrel
NSQ
RabbitMQ
Redis
ruby-nats
測試環境:
首先,讓我們來看看性能指標,因為這可以說是人們最關心的。我已經測量了兩個關鍵指標:吞吐量和延遲。
所有的測試都運行在一台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易於使用,易於部署和管理,並且占用空間相對較小。根據用例,它可以是一個偉大的選擇實時消息。