Twitter 的 Kafka 遷移歷程
Twitter 的實時性特點為 Twitter 的工程團隊帶來了獨特而具有挑戰性的問題。我們需要快速釋出突發新聞,向用戶提供相關廣告,並解決很多其他實時性問題。Twitter 的 Pub/Sub 系統為 Twitter 團隊提供了處理這些工作負載的基礎設施。
Twitter 的 Messaging 團隊過去幾年一直在執行一個內部 Pub/Sub 系統,叫作 EventBus(建立在 Apache DistributedLog 之上),但我們最近決定轉向 Apache Kafka,不僅針對已有的用例,還包括新增的用例。在這篇文章中,我們將介紹為什麼我們選擇採用 Kafka 作為 Twitter 的 Pub/Sub 系統,以及我們在遷移過程中遇到的各種挑戰。
Kafka 是什麼?
Apache Kafka 是一個開源的分散式流式處理平臺,可以高吞吐和低延遲地傳輸資料。Kafka 最初是在 LinkedIn 誕生,並於 2011 年開源,從那時起開始被社群廣泛採用,包括很多其他公司在內,使其成為業界首選的事實上的實時訊息系統。
Kafka 的核心就是一個基於分散式提交日誌構建的 Pub/Sub 系統,提供了很多非常好的特性,例如水平可伸縮性和容錯性。從那以後,Kafka 已經從訊息系統發展成為一個成熟的流式處理平臺。
為什麼要遷移?
你可能想知道為什麼 Twitter 需要自己構建內部的訊息傳遞系統。幾年前,Twitter 也曾經使用過 Kafka(0.7 版本),但我們發現在某些方面它無法滿足我們的要求——主要是在讀取期間進行的 I/O 運算元量,而且缺乏持久化特性和複製機制。然而,隨著時間推移,硬體和 Kafka 都已經走過了漫長的道路,這些問題現在都已經得到了解決。硬體的改進已經使 SSD 的價格足夠便宜,這解決了我們之前在 HDD 上看到的隨機讀取的 I/O 問題,而且伺服器 NIC 具有更多的頻寬,就沒有那麼必要分離服務和儲存層(EventBus 會這麼做)。此外,較新版本的 Kafka 現在支援資料複製,提供了我們想要的永續性保證。
將 Twitter 的所有 Pub/Sub 用例遷移到一個全新的系統將是一個非常耗費成本的過程。所以,遷移到 Kafka 的決定絕對不是自然發生的,而是經過精心策劃的,並且是由資料驅動的。遷移到 Kafka 的動機可歸納為兩個方面:成本和社群。
成本
在向整個公司宣佈遷移到 Kafka 之前,我們的團隊花了幾個月時間評估了 Kafka 在與 EventBus 類似的工作負載下的表現——持久寫入、尾部讀取、追趕讀取和高扇出讀取,以及一些灰色故障情況(例如減慢叢集中的特定 Kafka 代理)。
在效能方面,我們看到 Kafka 的延遲顯著降低,無論是根據訊息建立時間戳來衡量吞吐量,還是根據消費者讀取訊息時間戳來衡量吞吐量。
不同吞吐量下 EventBus 和 Kafka 之間的 P99 延遲比較
這可以歸因於幾個因素,可能包括但不限於:
- 在 EventBus 中,服務層和儲存層是分離的,這引入了額外的跳轉(網路時間和通過 JVM 代理層的時間),而在 Kafka 中只有一個程序處理儲存和請求服務(參見下圖)。
- EventBus 在通過 fsync() 呼叫進行寫入時會阻塞,而 Kafka 在後臺依賴作業系統進行 fsync()。
- Kafka 使用零拷貝。
EventBus(左)和 Kafka(右)之間的架構比較
從成本的角度來看,EventBus 需要服務層(針對高網路吞吐量進行了優化)和儲存層(針對磁碟進行了優化)的硬體,而 Kafka 使用單臺主機就可以提供這兩者。因此,EventBus 需要更多的機器來提供與 Kafka 相同的工作負載。對於單個消費者,我們節省了 68%的資源,對於擁有多個消費者的案例,我們節省了 75%的資源。但有一個問題是,對於嚴重依賴頻寬的工作負載(非常高的扇出讀取),EventBus 理論上可能更有效,因為我們可以獨立地擴充套件服務層。但是,我們在實踐中發現,我們的扇出沒有那麼極端,分離服務層是不值得的。
社群
如上所述,Kafka 已經得到了廣泛採用。我們可以利用數百名開發人員為 Kafka 專案所做出的貢獻,他們修復錯誤、改進和新增新功能,這比 EventBus/DistributedLog 的八名工程師所做的要好得多。此外,Twitter 內部使用者在 EventBus 中想要的很多功能已經在 Kafka 中提供了,例如流式處理庫、至少一次 HDFS 管道,以及恰好一次性處理。
此外,當我們遇到客戶端或伺服器問題時,我們可以通過搜尋網路輕鬆快速地找到解決方案,因為很可能其他人之前也遇到了同樣的問題。另外,相比不太受歡迎的專案,受歡迎的專案的文件通常更加詳盡。
採用 Kafka 等熱門專案,並向這些專案回饋我們的貢獻,這樣做的另一個重要原因是為了招聘。一方面,通過向 Kafka 社群回饋貢獻,可以讓人們瞭解 Twitter 的工程。另一方面,由於新工程師已經熟悉了這些技術,因此為團隊招聘工程師要容易得多。
挑戰
儘管遷移到 Kafka 看起來非常棒,但過程並不是一帆風順的。我們在這個過程中遇到了很多技術挑戰和適應性挑戰。
從技術角度來看,我們遇到的一些挑戰包括配置調優和 Kafka Streams 庫。與很多分散式系統一樣,為了支援 Twitter 的實時性用例,需要對大量配置進行微調。在執行 Kafka Streams 時,我們發現 Kafka Streams 庫中的元資料大小存在一些問題,這些問題是由於老版本的客戶端在關閉後仍然保留元資料造成的。
另一方面,Kafka 與 EventBus 存在架構差異,我們不得不以不同的方式配置系統和除錯問題。例如,如何在 EventBus(仲裁寫入)和 Kafka(主從複製)中完成複製。寫請求在 EventBus 中並行傳送,而 Kafka 要求從節點僅在主節點收到寫請求後才複製寫請求。此外,兩個系統之間的永續性模型是非常不同的—— EventBus 僅在資料持久化到磁碟時確認寫入成功,而 Kafka 複製本身就具有永續性保證,並在將資料持久儲存在磁碟上之前確認寫入請求。我們不得不重新考慮我們對資料永續性的定義:資料的所有三個副本同時失敗是不太可能的,因此沒有必要在每個副本中同步資料來提供我們想要的永續性保證。
前行
在接下來的幾個月裡,我們計劃將我們的使用者從 EventBus 遷移到 Kafka,這將有助於降低運營 Twitter Pub/Sub 系統的成本,並使我們的使用者能夠使用 Kafka 提供的其他功能。我們將持續關注生態系統中的不同訊息傳遞和流式處理系統,並確保我們的團隊為我們的使用者和 Twitter 做出正確的決策,即使這些決策很艱難。
英文原文:
ofollow,noindex">https://blog.twitter.com/engineering/en_us/topics/insights/2018/twitters-kafka-adoption-story.html