幾種分散式訊息系統比較(old)
0 引言
隨著網際網路行業的發展和IT技術在行業內的廣泛應用,許多網際網路企業的伺服器每天產生海量的日誌。如天翼閱讀平臺每天產生的PV日誌有上億條;淘寶網每天的使用者行為日誌達數TB大小。如何高效地收集日誌,並根據不同的時延要求向下遊系統轉發,是一個巨大的挑戰。
傳統日誌收集技術使用大容量高吞吐的日誌伺服器收集叢集中每臺機器的本地日誌,再向下游系統轉發。這種架構有以下缺陷:
n 業務伺服器需要先將記憶體資料持久化到硬碟,寫檔案操作耗時,且每臺主機均儲存大量(數以萬計甚至更多)個日誌檔案,掃描一遍即耗時很久。
n 日誌伺服器採集上游日誌通常使用Pull方式。當上遊業務伺服器叢集臺數較多時,由於檔案控制代碼、網路頻寬等諸多限制,日誌伺服器只能間隔一定時間(如
n 採集鏈路的負載均衡是人肉實現的,一旦上游伺服器叢集配置發生變化,需要大量人工配置以重新實現負載均衡。
n 日誌伺服器為保證效率,通常使用小型機掛載集中式儲存的模式,擴容困難且成本高昂。
為解決這些問題,近年來多家業界巨頭開發了自己的分散式訊息採集系統,其中有多個均已開源。這些系統的典型特徵有:
n 將業務伺服器和下游分析伺服器解耦,為兩者提供資料傳遞的橋樑。
n 較高的可靠性和擴充套件性,當採集的訊息規模擴張時,可通過增加叢集節點數量進行擴容。
n 能提供達毫秒級的轉發延遲,支援Storm這樣的實時計算框架和Hadoop這樣的離線計算框架。
本文試比較以下幾種系統的特性和優劣,希望能起到拋磚引玉的作用。
1 Kafka
Kafka是Linkedin於2010年12月開源的專案,使用scala語言編寫。(為避免學習scala這種較冷門又較古怪的語言,可參考Kafka的Java語言克隆物:Jafka)為實現高實時性和可擴充套件性,Kafka使用了多種效率優化方案,整體架構比較新穎。
主要特性:
n 使用zero-copy技術,資料在磁碟上存取代價為O(1)
n 高吞吐率,筆者的團隊測試,在千兆網下,單個broker每秒可處理數萬條1KB訊息,吞吐率高於30MB/s,即單點3萬TPS
n 顯式分散式,即所有的producer、broker和consumer都會有多個,均為分散式的
n 支援將資料並行的載入到
系統主要部件:
n Producer:向Kafka的主題(topic)傳送訊息,即上游伺服器向Kafka的broker push訊息的程序。Producer負責選擇某條訊息傳送給哪個topic的哪個partition。為實現負載均衡,使用者可使用簡單的round robin演算法或其他切片方法,亦或使用Kafka提供的高階介面中的Partitioner實現。比較遺憾的是,當前版本的Kafka並未提供producer和broker間的負載均衡機制,下文架構圖上將各臺broker連線到zookeeper,只是為了實現broker的自動識別。Producer可通過zookeeper獲取可用的broker列表,也可在zookeeper中註冊listener,當增加broker伺服器數量或broker掛掉時,均可以通知到producer,並採取相應的措施。
n Broker:Kafka叢集中的每臺伺服器即為一個broker,其採取了多種策略提高資料處理效率,包括zero-copy和sendfile呼叫等技術。
n Consumer:向一個或多個topic註冊,以接收發送到這些topic的訊息,即消費訊息的程序或伺服器。Kafka提供了兩種consumer介面:simple介面使用無狀態連線從broker pull資料,每次均需告訴broker偏移量;high level介面則隱藏了broker的細節,使用流方式從broker pull資料。另外,broker和consumer間使用zookeeper進行負載均衡。
圖表1 Kafka整體架構
筆者的團隊使用6臺PC Server作為broker測試Kafka效能,每臺4個CPU+32G記憶體。在啟動1個broker時,資料吞吐量約為30MB/s,陸續增加broker數量,當達到4個broker時,吞吐量約為130MB/s,達到千兆網路頻寬上限。說明Kafka有很好的橫向擴充套件能力,當增加節點數量時,吞吐量基本呈線性增長,見圖表2。
圖表2 broker數量和傳送速率
2 Flume
Flume是Cloudera於2009年7月開源的專案,使用Java編寫。它內建元件齊全,使用簡單,並且和Cloudera自己的Hadoop版本有很好的結合。Flume的歷史版本(1.0前,現稱為FlumeOG)採用agent,collector,storage的三層架構。為解決FlumeOG程式碼過於複雜、核心元件生命週期管理等問題,在1.0版本後(現稱為FlumeNG)架構有了較大的更新,下文均以FlumeNG為準。
主要特性:
n 高可靠性。Flume提供了end to end的資料可靠性機制,每次傳輸資料agent均將事件記錄到channel中,隨後將事件傳送給資料流中下一跳的agent或資料的最終儲存者,僅當下一跳的agent或資料的最終儲存者確認接收成功後,當前agent刪除訊息,如未確認或校驗失敗則重新發送。Flume還使用了事務機制來保證事件傳遞的可靠性。
n 易於擴充套件。Agent為分散式架構,可水平擴充套件。
n 易於恢復。Channel中儲存了於資料來源有關的事件,用於失敗時的恢復。Flume支援基於本地檔案系統的檔案channel。同時也支援基於記憶體佇列的記憶體channel,比檔案channel更快速,但當agent執行緒失敗時記憶體channel中尚未處理的事件無法用於恢復。
n 功能豐富。Flume內建了多種元件,包括不同資料來源(file, syslog, queue)使用的agent,各種儲存方式(Linux FS, HDFS等)。
系統主要部件:
n Agent:一個agent包含source、channel、sink和其他的元件。Flume就是一個或多個agent構成的。
n Source:資料來源。簡單的說就是agent獲取資料的入口。
n Channel:管道,資料流通和儲存的通道。一個source必須至少和一個channel關聯。
n Sink:用來接收channel傳輸的資料並將之傳送到指定的地方。傳送成功後資料從channel中刪除。
圖表3 Flume整體架構
筆者的團隊嘗試用Flume採集伺服器上的檔案日誌,並傳遞給下游Kafka系統。通過編寫KafkaSink,Flume可將channel中的資料向Kafka傳遞,作為Kafka的producer輸入,效果很好。
3 Chukwa
Chukwa是2009年11月開源的一個Apache專案,使用Java編寫,屬於hadoop系列元件中的一員,因此也引用了其他許多hadoop元件,如HDFS和MapReduce等。
主要特性:
n 靈活性,動態可控的資料來源
n 高效能,儲存系統具備高擴充套件性
n 提供了對收集到的大規模資料進行分析的框架
系統主要部件:
n Adaptor:用於封裝資料來源,目前支援多種資料來源,如hadoop logs,file,linux命令列,linux系統引數資料等。
n Agent:給adaptor提供各種服務,包括啟動和關閉adaptor,將資料傳遞給collector,記錄adaptor狀態用於失敗恢復等。
n Collector:可對多個數據源傳送來的資料進行合併,然後載入到HDFS中。鑑於HDFS適合處理少量大檔案和低併發的高速寫入,而日誌系統往往需要處理大量小檔案和高併發的低速寫入,為處理這對矛盾,Chukwa讓collector對小檔案進行合併後再寫入叢集。同時Chukwa允許設定多個collector,agent負責處理collector的單點故障或繁忙情況(但還不是負載均衡)。以上三者是Chukwa的3個主要角色。
n HDFS:Chukwa使用HDFS作為檔案系統。Collector上合併機制的存在使得使用HDFS儲存海量日誌成為可能。
n Demux和archive:Chukwa使用MapReduce分析叢集上的日誌檔案,為此提供了demux和archive兩種作業型別,demux作業負責對資料的分類、排序和去重;archive作業則負責把同類資料檔案進行合併。
n HICC:負責資料的展示。
圖表4 Chukwa整體架構
4 Scribe
Scribe是Facebook於2008年10月開源的訊息收集系統,在Facebook公司內部大量應用,使用C/C++編寫。它為日誌的分散式收集、統一處理提供了一個可擴充套件的、高容錯的方案。
主要特性:
n 高可靠性。當後端的儲存系統crash時,scribe會將資料寫到本地磁碟上,當儲存系統恢復正常後,scribe將日誌重新載入到儲存系統中。
n 資料來源須通過thrift傳輸資料,thrift客戶端可使用各種主流語言編寫。
n 支援多種儲存模式,包括file,thrift file,bucket(多個store),network(另一個scribe伺服器)等。
系統主要部件:
n Scribe agent:scribe agent實際上是一個thrift client。scribe內部定義了一個thrift介面,使用者使用該介面將資料傳送給server。
n Scribe:scribe接收到thrift client傳送過來的資料,根據配置檔案,將不同topic的資料傳送給不同的物件。
n Store:即後端儲存系統,scribe支援多種模式的儲存,包括file,thrift file,bucket(多個storage),network(另一個scribe伺服器)等
圖表5 Scribe整體架構
5 MetaQ
MetaQ(全名為Metamorphosis)是一個淘寶開源的分散式的訊息中介軟體,純Java開發,具有高吞吐量、高可用性、適合大規模分散式系統應用的特點。它總體設計和Kafka完全一致,但又針對淘寶業務特性做了很多優化改進。
主要特性(與Kafka相比獨特之處):
n 文字協議設計,非常透明,支援類似memcached stats的協議來監控broker
n 純Java實現,從通訊到儲存,從client到server都是重新實現
n 提供事務支援,包括本地事務和XA分散式事務
n 支援HA複製,包括非同步複製和同步複製,保證訊息的可靠性
n 支援非同步傳送訊息
n 消費訊息失敗,支援本地恢復
n 多種offset儲存支援,資料庫、磁碟、zookeeper,可自定義實現
n 支援groupcommit,提升資料可靠性和吞吐量
n 支援訊息廣播模式
n 一系列配套專案:python客戶端、twitterstorm的spout、tail4j等
系統主要部件和架構同Kafka基本一致。
該系統在阿里系公司內部廣泛應用,在淘寶每日支撐十億級條資料,在支付寶每日支撐百億級條資料。筆者的團隊也借鑑了MetaQ的部分亮點對Kafka做了一些優化,還為下游storm平臺開發了spout作為訊息輸入。
6 總結
以下是幾種分散式訊息系統的對比總結。可以看到,幾種系統在高可靠性、高擴充套件性方面大同小異,而訊息傳遞機制、持久化機制等方面又各具特色。同行們如需採用,可根據自身業務伺服器特點選擇最合適的系統,或選擇一個社群最活躍的系統以獲得可靠的技術支援。
專案 |
Kafka |
Flume |
Chukwa |
Scribe |
MetaQ |
公司 |
|
Cloudera |
Apache |
|
淘寶 |
原始碼語言 |
Scala |
Java |
Java |
C/C++ |
Java |
訊息傳遞 |
Push/pull |
Push/push |
Push/push |
Push/push |
Push/pull |
擴充套件性 |
好 |
好 |
好 |
好 |
好 |
容錯性 |
Producer和broker,broker和consumer間均有容錯機制 |
Agent和store間有容錯機制,agent內部事件傳遞時也有容錯 |
Agent和collector間有容錯機制 |
Scribe和store間有容錯機制,Scribe agent和Scribe間的容錯需自己實現 |
Producer和broker,broker和consumer間均有容錯機制 |
負載均衡 |
zookeeper |
zookeeper |
無 |
無 |
zookeeper |
持久化方式 |
多,支援HDFS |
中,支援HDFS |
中,支援HDFS |
多,支援HDFS |
多,支援HDFS |