1. 程式人生 > >Kafka 與RocketMQ 可靠性比較

Kafka 與RocketMQ 可靠性比較

引言

前幾期的評測中,我們對比了Kafka和RocketMQ的吞吐量和穩定性,本期我們要引入一個新的評測標準——軟體可靠性。

  • 何為“可靠性”

先看下面這種情況:有A,B兩輛越野汽車,在城市的周邊地區均能很好應對泥濘的路況。當一同開去穿越西藏,A車會因為西藏本地的汽油不達標,導致油路受阻無法點火,而B車順利完成了穿越。因此我們說,B車的可靠性比A車高。

  • 何為“軟體可靠性”

“軟體的可靠性”就是考察軟體在各種異常突發的情況下的應對能力。常見的軟體異常有:磁碟損壞、程序意外退出、宿主機宕機等情況。

  • 何為“訊息中介軟體的可靠性”

對於訊息中介軟體來說,“可靠性”最直接的指標就是——訊息資料不丟失。此外,訊息不重投、服務一主多備等特性也可以用來評估可靠性。

那麼Kafka和RocketMQ(以下簡稱RMQ)在可靠性上孰優孰劣呢?和我們走進本期的測試比拼吧!

測試目的

在訊息收發的過程中,分別模擬Broker服務程序被Kill、物理機器掉電的異常場景,多次實驗,檢視極端情況下訊息系統的可靠性。

測試場景

以下場景使用多個傳送端向一個Topic傳送訊息,傳送方式為同步傳送,分割槽數為8,只啟動一個訂閱者。

場景1. 模擬程序退出

在訊息收發過程中,利用Kill -9 命令使Broker程序終止,然後重新啟動,得到可靠性資料如下:

注:以上測試場景中Kafka的非同步刷盤間隔為1秒鐘,同步傳送需設定request.required.acks=1,否則會出現訊息丟失。

在Broker程序被終止重啟,Kafka和RMQ都能保證同步傳送的訊息不丟,因為程序退出後作業系統能確保將該程序遺留在記憶體的資料刷到磁碟上。實驗中,Kafka出現了極少量的訊息重複。再次可以確定此場景中,二者的可靠性都很高。

場景2. 模擬機器掉電

在訊息收發過程中,直接拔掉Broker所在的宿主機電源,然後重啟宿主機和Broker應用。因受到機房斷電限制,我們在本場景測試中使用的是普通PC機器。得到可靠性資料如下:

測試發現,即使在併發很低的情況下,Kafka和RMQ都無法保證掉電後不丟訊息。這個時候,就需要改變刷盤策略了。我們把刷盤策略由“非同步刷盤”變更為“同步刷盤”,就是說,讓每一條訊息都完成儲存後才返回,以保證訊息不丟失。
注:關於兩種刷盤模式的詳細區別可以參照文件最下方的說明

重新執行上面的測試,得到資料如下:

首先,設定同步刷盤時,二者都沒出現訊息丟失的情況。限於我們使用的是普通PC機器,兩者吞吐量都不高。此時Kafka的最高TPS僅有500條/秒,RMQ可以達到4000條/秒,已經是Kafka的8倍。

為什麼Kafka的吞吐量如此低呢?因為Kafka本身是沒有實現任何同步刷盤機制的,就是說在這種場景下測試,Kafka註定是要丟訊息的。但要想做到每一條訊息都在落盤後才返回,我們可以通過修改非同步刷盤的頻率來實現。設定引數log.flush.interval.messages=1,即每條訊息都刷一次磁碟。這樣的做法,Kafka也不會丟訊息了,但是頻繁的磁碟讀寫直接導致效能的下降。

另外,二者在服務恢復後,均出現了訊息重複消費的情況,這說明消費位點的提交併不是同步落盤的。不過,幸好Kafka和RMQ都提供了自定義消費位點的介面,來避免大量的重複消費。

測試結論

  1. 在Broker程序被Kill的場景, Kafka和RocketMQ都能在保證吞吐量的情況下,不丟訊息,可靠性都比較高。
  2. 在宿主機掉電的場景,Kafka與RocketMQ均能做到不丟訊息,此時Kafka的吞吐量會急劇下跌,幾乎不可用。RocketMQ則仍能保持較高的吞吐量。
  3. 在單機可靠性方面,RocketMQ綜合表現優於Kafka。

附錄:

測試環境

服務端為單機部署,機器配置如下:

應用版本:

測試指令碼

同步刷盤和非同步刷盤的區別

同步刷盤是在每條訊息都確認落盤了之後才向傳送者返回響應;而非同步刷盤中,只要訊息儲存到Broker的記憶體就向傳送者返回響應,Broker會有專門的執行緒對記憶體中的訊息進行批量儲存。所以非同步刷盤的策略下,當機器突然掉電時,Broker記憶體中的訊息因無法刷到磁碟導致丟失。