kafka是一個分布式的,高吞吐量的、信息分片存儲,消息同步復制的開源消息服務,它提供了消息系統的功能,但是采用了獨特的設計。
kafka最初由LinkedIn設計開發,使用Scala語言編寫,用作LinkedIn網站的活動流數據和運營數據處理工具,這其中活動流數據是指頁面訪問量、被查看內容方面的信息以及搜索情況等內容,運營數據是指服務器的性能數據(CPU、IO使用率、請求時間、服務日志等數據)。
現在kafka已被多家不同類型的公司采用,作為其內部各種數據的處理工具或消息隊列服務。如今kafka捐獻給了apache軟件基金組織,成為apache下的一個開源項目。
下面我們來溫習一下消息系統的基本要素:
1、topic:kafka維護的一個叫topic的消息主題;
2、producer:我們將消息發布到kafka的topic上,發布消息的進程也叫生產者producer;
3、consumer:我們從kafka的topic上訂閱消息,訂閱消息的進程叫消費者consumer;
4、broker:kafka運行在由一個或多個服務器構成的集群上,集群中的每一臺服務器被稱為broker。(broker的意思為:經紀人、居間人、代理人)
所以從宏觀上來看,生產者(producer)通過網絡發布消息到kafka集群(cluster),kafka集群再為消費者(consumer)提供消息服務,他們的處理流程如下圖所示:
生產者、消費者與kafka的broker服務器之間通過TCP協議通信。kafka提供了多種語言客戶端Java、C/C++、Python、php、ruby、.net、scala、erlang等,用于與kafka交互。
我們將消息的發布(publish)叫做生產者producer,將消息的訂閱(subscribe)叫做消費者consumer,將中間的存儲服務叫做broker,這個broker就是我們的kafka服務器,生產者通過推模式將數據推到kafka服務器broker,消費者通過拉模式從kafka服務器broker拉取數據,它們如下圖所示:
需要注意的是,消費者是自己主動從broker拉取數據,而broker不會主動把數據發送到消費者。
對于在實際應用中,生產者、消費者和kafka的broker一般集群部署,多個producer、consumer和broker之間協同合作,通過zookeeper協調管理,構成了一個高性能的分布式消息發布與訂閱系統,在一個集群中,它們的結構如下圖所示:
構成的整個分布式消息系統將按照如下的流程運行:
1、啟動zookeeper
2、啟動kafka的broker
3、編寫客戶端Producer生產數據,通過zookeeper找到broker,然后將數據存入broker
4、編寫客戶端Consumer消費數據,通過zookeeper找對應的broker,然后從broker消費消息。
以上我們對kafka有了一個概括性的描述,讓我們從宏觀上認識了kafka是什么以及其基本工作原理,接下來我們再詳細看看kafka涉及到的幾個主要要素都有些什么特點:
Topic,高級別抽象的kafka提供者,一個topic是一個目錄或消息名,消息將被發送到topic,對于每個topic,kafka維持一個分片日志(partitioned log),如下圖所示為一個topic的解剖圖:
每一個分片日志都是有序的、不可變的消息系列,新的消息不斷地添加到分片日志的末尾,在這個分片日志中,每個消息被分配一個連續的id號叫offset,它唯一地定義了一個消息。
在一個配置的時間內,kafka集群一直保留著所有發布的消息,不管這些消息有沒有被消費。比如被設置保留兩天,那么一個消息被發布后的兩天時間內,消息都是可以被消費的,兩天之后消息將被丟棄以釋放空間。
kafka中進行partitions設計有多個原因,首先,通過partition可以使log文件的大小不會超過單臺機器的文件容量限制,一個topic可以有多個partitions,因此可以存儲任意數量的數據。其次,可以提升并發消費的能力,一個topic的partitions可以被分布在kafka集群中的多臺機器上,每臺機器上的kafka實例負責該機器上分片數據的請求和操作,每個分片可以配置被復制的份數,從而復制到集群中的其他機器上,以提升高可用性。
每個partition有一個server作為leader,0個或者多個server作為followers,leader處理所有的讀寫請求,followers復制leader進行消息同步,如果一個leader發生故障,followers中會自動有一個follower變成新的leader。
生產者把消息發送到他們選擇的topics中,producers還能指定發送到topic的哪個partition中,你可以通過round-robin或者其他算法來決定把消息發送到哪個partition中。
傳統的消息系統有兩種模式:
一種是基于隊列Queue的點對點消息。
一種是基于主題Topic的發布與訂閱消息。
基于隊列的點對點消息只能被一個消費者消費,而基于主題的發布與訂閱消息能被多個消費者消費。kafka抽象了這兩種模式,它采用consumer group名稱來處理這兩種模式,可以將消費者分成多個group,每個consumer屬于一個單獨的consumer group,也可以多個consumer屬于同一個group。
如果采用基于隊列的點對點消息,則每個消費者都需要位于同一個group中,如果采用基于主題的發布訂閱消息,則每個消費者都要位于不同的group中。
在更多的情況下,我們的主題topic中會包含幾個consumer group,每個consumer group都是一個logical subscribe,每個group包含了多個consumer實例,這樣更具擴展性和容錯性。kafka有比傳統消息系統更強健的訂閱機制。
kafka在較高的層次上提供了如下保證:
1、生產者producer發送到topic partition中的消息會被順序的追加到日志中;
2、消費者consumer消費消息的順序和消息在日志中的順序一致;
3、如果一個topic有N份復制,則我們可以允許N-1臺服務故障而不會丟失任何消息。
kafka的一些常用應用場景:
1、消息系統:替換傳統的消息系統,解耦系統或緩存待處理的數據,kafka有更好的吞吐量,內置了分片、復制、容錯機制,是大規模數據消息處理的更好的解決方案。
2、網站活動跟蹤:網站的訪問量,搜索量,或者其他用戶的活動行為如注冊,充值,支付,購買等行為可以發布到中心的topic,每種類型可以作為一個topic,這些信息流可以被消費者訂閱實時處理、實時監控或者將數據流加載到Hadoop中進行離線處理等。
3、度量統計:可以用于度量統計一些運維監控數據,將分布式的一些監控數據聚集到一起。
4、日志聚合:可以作為一個日志聚合的替換方案,如Scribe、Flume。
5、數據流處理:可以對數據進行分級處理,將從kafka獲取的原始數據進行加工潤色后再發布至kafka。
6、事件溯源:可以以時間為順序記錄應用事件的狀態變化,從而為事件溯源。
7、提交日志:可以作為分布式系統的外部日志存儲介質。
當然也許還可以以其他方式更加巧妙地使用kafka。
一個Java技術交流群,一起交流,共同進步,扣扣群號:513086638
微信公眾平臺: