Apache Kafka 的高效能一直廣受喜愛,它能在高速處理訊息的同時維持低延遲。Apache Pulsar 在同類產品中發展迅速,競爭力突出。
總有文章說 Pulsar 比 Kafka 效能更好,但是想找到測試的原始資料並不容易。另外,很多報告的測試資料並非來自最新版本的 Pulsar 和 Kafka,這兩個專案都發展得太快了,因此測試結果對新版本不具有代表性,所以我們決定使用Kafka(2.3.0)和 Pulsar(2.4.0),進行一系列效能測試,並將測試結果陸續釋出出來。
本系列文章將重點討論延遲性,後續文章中會討論吞吐量等。
訊息系統效能測試
Kafka 和 Pulsar 軟體包都包含效能測試工具。我們可以修改任何一個效能測試工具,讓它們彼此相容。我們將使用 OpenMessaging Project 的第三方基準框架。
可參考:http://openmessaging.cloud/
OpenMessaging Project 是一個 Linux Foundation Collaborative Project。OpenMessaging Project 的目標是為訊息和流技術提供廠商中立且適用於所有程式語言的標準。這一專案採用了支援多種訊息技術的效能測試框架。
測試使用的程式碼都在 OpenMessaging GitHub 倉庫中。
可參考:https://github.com/openmessag...
測試最初被設計為在公有云產品上執行,但我們將在 Amazon Web Services(AWS)中使用標準 EC2 例項進行測試。
我們將在 GitHub 上釋出每個測試的完整輸出結果。歡迎你分析資料並提出見解,當然,你也可以自己測試,獲取新資料。我們發現,使用不同系列的 EC2 例項集進行測試,結果相近,因此你的測試結果也不會與我們相差很多。
雖然使用 OpenMessaging 基準工具來執行的測試已經包含了大量工作負載,但是為了讓對比測試更有趣,我們決定再加一些負載,這一想法來自 LinkedIn Engineering 網站上一篇名為「Benchmarking Apache Kafka: 2 Million Writes Per Second (On Three Cheap Machines)」的文章。
可參考:https://engineering.linkedin....
這是一篇很久以前的部落格了,現在,硬體普遍更好,但是我們並未使用頂配的測試裝置。提前劇透:Kafka 和 Pulsar 都可以毫不費力地處理每秒 200 萬次的寫入,會在後續文章中詳述。
OPENMESSAGING 基準測試
OpenMessaging 基準測試是一個開源的可擴充套件框架。只需新增 Terraform 配置、Ansible playbook 或能在測試工具中控制 producer 和 consumer 的 Java 庫,就可以把訊息技術新增到測試中。目前,Kafka 和 Pulsar 中的 Terraform 配置是相同的,在 AWS 中啟動相同的 EC2 例項集。
為了便於比較,硬體配置應該相同,因此,現有的基準程式碼簡化了 Kafka 和 Pulsar 之間的比較。
在實際測試開始前,我對所有測試進行了預測試。以恆定速率進行了延遲測試,定期記錄延遲和吞吐量。
如果你想自己測試的話,需要注意以下幾點:在 AWS 上執行測試費用很高;需要大量配置較好的 EC2 例項(對軟體基準測試非常重要);如需保證硬體不成為瓶頸,則需配置較好的硬體,而它的成本比較高(每小時不低於 5 美元,一個月要 3800 美元);在不進行測試時(例如,夜裡),可以停止執行環境;確保在測試後刪除所有資源。
效能注意事項
為了更好地理解測試結果,先介紹幾個重要概念。首先,需要檢查測試的目的:延遲;然後,檢查訊息的永續性,尤其是在將訊息儲存到磁碟時;最後,需要了解 Kafka 和 Pulsar 中不同的訊息複製模型。
Kafka 和 Pulsar 之間有許多相似之處,但也有一些影響效能的顯著差異。為了公平地評估這兩個系統,需要了解以下差異:
關於延遲測試
所有延遲都必須包含應用程式和訊息系統之間的網路延遲。假設所有測試的網路配置相同,並且網路產生的延遲也相同,那麼網路延遲對所有測試的影響是相同的。在比較延遲時,相同的網路延遲很重要。
我們指出這一點是因為測試結果與 LinkedIn Engineering 部落格中的結果不相同。假設部落格文章當時的測試在專用的 1 GB 乙太網上執行,而我們的測試執行在公有云的例項上,網路頻寬為 10 GB。所以,我們的測試結果與那篇文章中的結果直接相比確有不妥。由於在測試中,網路配置是恆量,我們可以比較本次測試中 Kafka 和 Pulsar 訊息系統之間的延遲結果。
我們記錄了兩種型別的延遲:端到端延遲和釋出延遲。
端到端延遲
端到端延遲相對簡單,指從 producer 傳送訊息到 consumer 接收訊息的時間。在實現 Pulsar 和 Kafka 的基準測試中,傳送的時間戳是由各自傳送訊息的 API 自動生成的。當 consumer 接收到訊息時,生成第二個時間戳。這兩個時間的差就是端到端延遲。
端到端延遲的複雜之處在於用於測量時間戳的時鐘。在測量端到端延遲時,必須同步時間戳的時鐘。如果沒有同步,時鐘之間的差異將會影響測量。最終測量結果實際上是時鐘之間的差異,也就是訊息系統的延遲。由於時鐘會隨時間漂移,所以在執行時間長的測試中問題會更嚴重。
理想情況下,producer 和 consumer 在同一伺服器上,使用同一時鐘獲得時間戳,因此不存在延遲。但是,基準測試的目的是將 producer 和 consumer 分離到不同的伺服器上,以分配負載。
另一個最佳方案是儘可能準確地同步伺服器之間的時鐘。AWS 提供免費的時間同步服務(time sync service),該服務與 chrony 相結合,使 EC2 例項之間的時鐘看起來十分接近同步(誤差在幾微秒內)。在測試中,我們特地在所有客戶端伺服器上安裝了 chrony,並配置使用 AWS 時間源。
釋出延遲
釋出延遲指訊息從 producer 發出到 broker 的這段時間。訊息被 broker ack 後,則表明訊息被正確地傳送到了 broker 且已被持久化。Procuder、broker、consumer 三者相互獨立,當 producer 完成傳送訊息操作之後(收到 ack 指令之後),這條訊息的成功與否已經和 producer 沒有關係了。一致的低釋出延遲對 producer 來說是有益的,在 producer 準備傳送訊息時,broker 快速接收訊息,允許 producer 繼續處理 producer 級別的問題,例如,業務邏輯。這種訊息的傳送是 broker 的關鍵特性。
在基準測試中,訊息採用非同步傳送的形式,即 producer 不會阻塞訊息 ack 的操作。傳送訊息的呼叫立即返回,回撥在訊息到達時進行確認。在非同步傳送中,釋出延遲看起來似乎沒那麼重要,但其實不然。
Kafka: max.in.flight.requests.per.connection
Pulsar: maxPendingMessages
以上兩者都有緩衝區,用來儲存未確認的訊息。當緩衝區達到設定的閾值時,producer 開始阻塞(或停止,這由配置決定)。因此,如果訊息系統沒有快速確認收到訊息,生產應用程式就會等待訊息系統的操作。
在基準測試中,釋出延遲指從呼叫傳送方法到觸發確認回撥的這段時間。這兩個時間戳都是在 producer 中生成的,因此無需考慮時鐘同步。
永續性與重新整理訊息到磁碟
訊息系統的永續性指在系統出現故障時,訊息不會丟失。為了確保這一點,需要將訊息儲存在安全的位置,即便執行訊息系統軟體的伺服器出現故障,訊息也不會丟失。Kafka 和 Pulsar 最終都向磁碟寫入訊息,以提供永續性。
但是,只要求作業系統向檔案系統寫入訊息是不夠的。向檔案系統寫入意味著將資料存放在寫入快取,但不一定安全地儲存在磁碟上。由於快取駐留在記憶體中,因此如果伺服器崩潰(例如,斷電、核心當機),已經寫入快取但還沒有寫入或重新整理到磁碟的資料將會丟失。強制將快取資料寫入磁碟的操作稱為 fsync。為確保訊息已經儲存在磁碟上,需要觸發 fsync 操作,在寫入訊息後將檔案快取重新整理到磁碟。
預設情況下,Kafka 不會顯式地將每條訊息重新整理到磁碟,它會在重新整理作業系統時實現磁碟重新整理。當伺服器崩潰時,未重新整理到磁碟的資料可能會丟失。這一預設設定是出於效能考慮的。寫入磁碟比寫入記憶體快取慢,因此磁碟重新整理使訊息處理效能下降。可以將 Kafka 配置為定期重新整理(甚至可以設定為每條訊息寫入後重新整理),但是出於效能考慮,不建議這樣做。
預設情況下,Pulsar 將每條訊息重新整理到磁碟。訊息存入磁碟後才向 producer 確認,這在伺服器崩潰時提供了更強的永續性保證。Pulsar 在保證永續性的同時,還能保持高效能,是因為它使用 Apache BookKeeper 來儲存訊息,而 BookKeeper 是專門為此優化的分散式日誌儲存系統。另外,在 Pulsar 中可以禁止 fsync 操作。
由於重新整理磁碟會影響效能,我們將對 Kafka 和 Pulsar 都進行兩次測試,一次啟用對每條訊息進行磁碟重新整理,一次禁用。這有助於更好地比較 Kafka 和 Pulsar。
訊息複製
Kafka 和 Pulsar 都通過多副本機制來確保訊息的高可用。即使丟失了一個訊息副本,仍然可以通過其他副本恢復訊息。在 Kafka 和 Pulsar 中,訊息複製影響效能的方式不同。如何確認測試中 Kafka 和 Pulsar 之間的複製行為相似?
Kafka 使用 leader-follower 複製模型。Kafka 的一個 broker 被選為分割槽的 leader。首先將所有訊息寫入 leader,follower 從 leader 中讀取並複製訊息。Kafka 監控每個 follower 是否與 leader “同步”。使用 Kafka,可以在訊息成功儲存並被 producer 確認之前控制單個訊息的總副本數(複製因子)與需要同步的最小副本數(min.insync.replicas
)。
典型的配置情況是,Kafka 儲存訊息的 3 份副本,並且只會在至少 2 個副本(大多數)成功寫入後立刻確認。這也是我們在所有 Kafka 測試中採用的配置(replication-factor
=3,in.sync.replicas
=2,acks
=all)。
Pulsar 採用 quorum-vote
複製模型。並行寫入多個訊息副本。一旦確認已儲存部分訊息副本,便會確認該訊息(ack quorum
)。Leader-follower 模型通常向特定主題分割槽內的同一組 leader 和 follower 寫入副本,而 Pulsar 可以將訊息副本均勻分攤到不同的儲存節點上,從而提高讀寫效能。
在測試中,為了確保測試的一致性,Pulsar 也採用三副本的機制。Pulsar(配置:ensemble
=3, write
`quorum=3,
ack quorum`=2)與 Kafka 的複製結果相似:3 個訊息副本,在得到其中任意兩個副本的確認之後,立即向 broker 返回訊息持久化成功。
點選 連結 ,可以檢視英文原稿。