消息隊列(Message Queue),簡稱MQ,本質是一個隊列,用於存放數據(message),先入先出(FIFO)。主要用於系統解耦、消息緩存。
目前市面上消息隊列的實現有很多種,下面調研了kafka/rabbitMQ/rocketMQ,這三種應用都非常廣泛,期望從中選出最合適我們的。
簡介
- Kafka是LinkedIn開源的分布式發布-訂閱消息系統,目前歸屬於Apache定級項目。Kafka主要特點是基於Pull的模式來處理消息消費,追求高吞吐量,一開始的目的就是用於日志收集和傳輸。0.8版本開始支持復制,不支持事務,對消息的重復、丟失、錯誤沒有嚴格要求,適合產生大量數據的互聯網服務的數據收集業務。
- RabbitMQ是使用Erlang語言開發的開源消息隊列系統,基於AMQP協議來實現。AMQP的主要特征是面向消息、隊列、路由(包括點對點和發布/訂閱)、可靠性、安全。AMQP協議更多用在企業系統內,對數據一致性、穩定性和可靠性要求很高的場景,對性能和吞吐量的要求還在其次。
- RocketMQ是阿里開源的消息中間件,它是純Java開發,具有高吞吐量、高可用性、適合大規模分布式系統應用的特點。RocketMQ思路起源於Kafka,但並不是Kafka的一個Copy,它對消息的可靠傳輸及事務性做了優化,目前在阿里集團被廣泛應用於交易、充值、流計算、消息推送、日志流式處理、binglog分發等場景。
原理
- kafka:每台服務器為一個broker,每種消息為一個topic,每個topic分為1或多個partition。每個partition為一個物理文件存儲,且是排序存儲的。消息存儲時,會復制到其他broker上,一台broker掛了后保證消息不丟失。
- rocketMQ:與kafka類似,每台服務器為一個broker,每種消息為一個topic,每個topic分為1或多個queue。每個broker可以配置主從,來實現高可用。主從間可采用同步或異步策略來復制消息。
- rabbitMQ:每台服務器為一個broker,發送方發送消息時每類消息有一個RoutingKey,接受方監聽一個消息存儲的queue,中間有個exchange將RoutingKey按照路由規則放到指定的queue中。
特性對比
特性 | kafka | rabbitMQ | rocketMQ |
可用性 | 很高 | 高 | 高 |
持久化 | 支持 | 支持 | 支持 |
順序消費 | 支持 | 支持 | 支持 |
事務 | 不支持 | 支持 | 支持 |
單機吞吐量 | 十萬級 | 萬級 | 十萬級 |
文檔完備性 | 高 | 高 | 高 |
多語言支持 | 支持 | 支持 | 支持 |
消息通知方式 | pull | pull & push | pull |
高可用性
kafka:分布式部署,數據會被負復制到其他節點,一個節點掛了后,會自動切換到其他節點。
rocketMQ:主從結構,數據會負責到從節點,主節點掛了會從從節點選舉一個主節點出來
rabbitMQ:有普通模式和鏡像模式,鏡像模式支持高可用,此模式下,隊列的數據復制一份到所有節點上。主節點失效時,mirror queue內部有一套選舉算法,會選出一個master,和若干個slaver。
順序消費消息
kafka:支持。但一個節點失效后,順序會被打亂,但不是丟失。
rocketMQ:支持。一個節點失效后,發送消息會失敗,此節點恢復后,能發送成功且順序不變。
rabbitMQ:支持。
分布式事務
kafka:不支持
rocketMQ:支持。用兩段提交來實現,第一階段發送消息時,拿到消息offset,第二階段通過 offset來修改消息狀態。
rabbitMQ:支持。可用兩段提交或者confirm機制來實現。confirm機制:發送方發送消息,broker立即返回ok,broker異步處理消息,將處理結果通知發送方。
結論
沒有哪種有明顯的優勢,kafka在於分布式架構,rabbitMQ基於AMQP協議來實現,rocketMQ思路來源於kafka,改成了主從結構,在事務性可靠性方面做了優化。寬泛來說,電商、金融等對事務性要求很高的,可以考慮rabbitMQ和rocketMQ,對性能要求高的可考慮kafka。
個人比較傾向於kafka,它的加分項:分布式架構的高可用性,便捷的擴展性。
【本文由“科學視角”發布,2017年5月9日】