817
技術社區[雲棲]
Kafka介紹
本文介紹LinkedIn開源的Kafka,久仰大名了,按照其官方文檔做些翻譯和二次創作。對應可以查看整份官方文檔。
基本術語
topics,維護的消息源種類(更像是業務上的數據種類/分類)
producer,給kafka的某個topic發布消息的進程
consumer,訂閱和處理topic的消息的進程
broker,組成kafka集群的server
Topic和日誌
kafka為每個topic維護了如下一份被分區了的log
每份log有序,不可變,不斷被append。分區中的消息會被分配一個有序的id,稱為offset。
kafka內保留的消息是有時間限製的,超出設定的時間段的話,消息就不保留了。kafka的性能與數據容量是成正比的。
offset能方便consumer來取數據,自由度比較大(或者說這種緩存性質的消息隊列,方便消費者讀取一定窗口內的消息,也算一種回放功能吧)。
分區一方麵是為了增大消息的容量(可以分布在多個分區上存,而不會限製在單台機器存儲大小裏),二方麵可以類似看成一種並行度。
分布
partitition分布在不同機器上,且可以設置備份數以達到容錯。
每份partition都有一個扮演leader角色的server和幾個扮演follower角色的server。leader來負責對這份分區的讀寫請求。
follower被動複製leader動作。leader掛了的話會有follower自動成為新的leader。
各個server都會各自扮演某份分區的leader和其他幾份分區的followe,如此的話整個集群上的機器相對負載比較好些。
生產者
生產者選擇發布數據給topic,負責選擇topic的哪個partition,把消息寫進去。
選擇方法和策略有多種。
消費者
傳統的消息模型有兩種模型,隊列模型和發布-訂閱模式。
1. 隊列形式中,一群消費者可能從server那邊讀消息,而每條消息會流向他們中的一個。
2. 發布-訂閱模式中,消息會廣播到所有它的消費者們那。
Kafka是使用consumer group這個概念(下麵把它翻譯為"消費組"),把兩者結合了。。
消費者給自己標誌了一個消費組名,每條新發布到topic的消息會被傳遞給訂閱它的消費組裏的消費者實例,這些消費者實例可以是不同的進程,存在在不同的機器上。
如果所有的消費者在同一個消費組裏,那麼這相當於是一個隊列模型的場景。
如果所有的消費者都屬於不同的消費組,那麼這相當於是一個發布-訂閱模式的場景,所有消息會廣播到所有消費者們。
下圖展示的是兩台server組成的Kafka集群,共4個分區,兩個消費組,A、B消費組各有2個、4個消費者,他們對應訂閱了不同的分區。
此外,Kafka比傳統的消息係統具備更強的有序性保證。下麵會展開說明。
傳統的隊列形式的消息係統,在server端是有序保存著消息的。但當有多個消費者來並發取queue裏的消息的時候,由於每個queue裏的消息是異步輸送給消費者,雖然輸出是有序的(隊列裏排好隊輸出的),當消息到達消費者那頭的時候,就不保證順序了。如果單個消費者來取,可以保證有序,某些中庸的解決辦法還是會喪失一定並行度。
Kafka是怎麼做到更好的並行且有序的呢?Kafkad的"分區"其實是一種並行度的概念,即在topic內,kafka的消費者進程池能得到有序性保證和負載均衡。這是因為在topic內設置了多個分區,使得topic對應的消費組裏的消費者們各自可以獨享一個分區。如此的話,每個消費者是其消費的分區的唯一reader,在單個reader下當然保證了有序這件事。而且多個分區也使得負載可以比較平衡。需要注意的是,消費者不能比分區數多。
保證
kafka能保證的幾件事情,
1. 生產者向topic分區發來的消息能按序添加進來。即先送來的消息在log裏麵有更小的offset。
2. 消費者實例能在log裏(第一張圖裏)看到有序的消息。
3. 一個擁有N個分區的topic,係統能容忍N-1台server失敗,而不丟失寫到了log裏的消息數據。
更多設計上的內容不在這裏闡述。
適合場景
消息隊列
kafka作為消息隊列,優勢在更好的吞吐,內置分區,副本數,容錯這幾個特性,所以適合大規模消息處理應用。
MQ有很多,就不具體比較了。
網頁行為追蹤
kafka原本的一個應用場景,就是跟蹤用戶瀏覽頁麵、搜索及其他行為,以發布-訂閱的模式實時記錄到對應的topic裏。
那麼這些結果被訂閱者拿到後,就可以做進一步的實時處理,或實時監控,或放到hadoop/離線數據倉庫裏處理。
行為追蹤經常會有很大的吞吐量。
元信息監控
作為操作記錄的監控模塊來使用,即匯集記錄一些操作信息,可以理解為運維性質的數據監控吧。
日誌收集
日誌收集方麵,其實開源產品有很多,包括Scribe、Apache Flume。如果談Kafka的優勢的話,其實還是離不開他的容錯、高吞吐性能方麵的設計層麵的特點吧。具體就不分析了。
參考我之前寫的分布式日誌收集係統Apache Flume的設計介紹
流處理
這個場景可能比較多,也很好理解。保存收集流數據,以提供之後對接的Storm或其他流式計算框架進行處理。
Commit Log
為分布式係統的一些commit log(操作日誌)做容錯意義的備份,我是這麼理解的,類似於HDFSnamenode的log。對比BookKeeper,其實就是做這件事的。BookKeeper在Hadoop HDFS Namenode HA方案裏,用於記錄namenode的操作日誌(一時想不起叫什麼log了,反正不記錄namenode的image數據)。
參考我之前寫的BookKeeper設計介紹及其在Hadoop2.0 Namenode HA方案中的使用分析全文完 :)
最後更新:2017-04-03 08:26:14