一、前言
随着技術不斷的成熟及市場需求的日益旺盛,實時開發已經成為目前大資料開發不可或缺的一部分。在整個實時開發的鍊路中,資料采集需要寫入到Kafka,資料處理也需要使用到Kafka。今天我們就針對Kafka這個時下主流的消息中間件進行簡單的介紹。
二、消息隊列:資料流的歸宿
在實時開發的場景中,來源于各類行為、事件的資料是随着發生時間源源不斷如同河流一般進入實時任務并不斷産出結果的。傳統的異構資料源,資料以結構化的形式存儲在對應的庫表内。那麼除了資料本身包含的業務時間屬性,要如何找到一個穩定的時間次元來描述這些資料的先後呢?又要将流式的資料放在哪裡去進行處理?
消息隊列就是為了應對大量資料需要傳遞、分析場景所涉及的。
目前消息隊列的方式分為以下兩種:
- 點對點(point to point,queue):消息被任一消費者消費後即消失在點對點系統中,消息被保留在隊列中,一個或多個消費者可以消耗隊列中的消息,但是特定消息隻能由最多一個消費者消費,一旦消費者讀取隊列中的消息,它就從該隊列中消失。
- 釋出-訂閱(publish/subscribe,topic):消息可被所有訂閱者(組)消費在釋出-訂閱系統中,消息生産者稱為釋出者,消息消費者稱為訂閱者。釋出者釋出的消息被保留在 Topic 中,與點對點系統不同,消費組可以訂閱一個或多個主題并使用該主題中的所有消息,同樣,所有釋出到Topic的消息均可被所有訂閱組消費。一個訂閱組内可能包含多個訂閱者。
為了更好的了解消息隊列的運作方式,我們先設想如下一個場景:資料是一份快遞,資料在不同開發環節之間的流轉就是快遞的配送過程。
1、電視購物:上門配送,客戶簽收
在10年前電視購物還比較盛行的時代,多數貨物是通過郵政等快遞公司進行上門配送,往往快遞員上門後,會讓客戶在運單上簽字驗收。這時候的快遞員,隻有每一份快遞被客戶簽字驗收後,才會再開始下一件貨品的運輸(此為極端情況下的舉例)。
當一個客戶存在多個快遞,并且多個快遞是陸續到達的時候,就會出現快遞員配送-等待簽收-客戶簽收-快遞員回到收發點發現新的快遞-快遞員配送這樣一個反複鍊路,如果存在客戶反應慢,簽字速度慢的情況,則會花費更多時間。
同樣,在傳統的資料開發場景中,資料傳輸也遵循這樣的規律。上下遊的兩個服務之間對資料進行傳輸等同于快遞配送的過程,如果一次資料傳輸需要等到下遊服務給到的回執來保證資料正常寫入,再開始下一次的進行,那麼下遊服務處理速度及響應速度會嚴重影響這一環節的資料進而導緻資料延遲;如果整條資料傳輸的鍊路包含了多個這樣的程序,整體資料的時效性就無法得到保證。
2、快遞物流:統一快遞站
随着網絡購物的不斷發展,為了提高效率,現在的貨物配送方式發生了極大的改變。現在快遞員從收發點揀貨出發,将快遞配送至相應地區的快遞站,由快遞站替實際使用者進行一次代理簽收,此時視作快遞配送的過程已經完成。快遞員就可以快速回到揀貨點,後續快遞站會以各類形式通知到具體的使用者,有相應的快遞需要簽收,在“某某時間點”前來到快遞點拿取。對于使用者而言,它隻需要持續關注快遞站的狀态(訂閱),當有快遞時,及時去取就可以。
當我們熟悉了快遞從倉庫中存儲到配送到收件人手中的流轉過程時,我們就能夠了解消息中間件是如何在實時開發的過程中運作的。那麼在多種消息中間件中,目前應用最廣泛的就屬Apache Kafka。
三、Kafka:消息中間件
Apache Kafka是一個分布式、支援分區的(partition)、多副本的(replica),基于zookeeper協調的分布式消息系統,用于實時處理大量資料,常用于大資料,資料挖掘等場景。
Kafka中經常會涉及到如下基本概念:
- Zookeeper:用于将獨立的Broker配置成Kafka叢集;
- Broker:Kafka叢集包含一個或多個伺服器,這種伺服器被稱為Broker;
- Topic:Kafka中的消息主題,類似于Table的概念,用于區分不同消息;
- Partition:Topic分區,每個topic可以有多個分區,分區的作用是友善拓展,提高并發。

為了便于了解,我們可以簡單的将Kafka與快遞過程進行類比如下:
1、資料寫入
1)确定Topic及Partition
一個Topic下可能存在多個Partition,在向Kafka寫入資料時需要先确定Topic及對應的Partition。
2)找到Partition通信位址
由于Kafka實作了高可用,确定寫入Partition後,Producer會從ZK中擷取到對應Partition的Leader并與其通信。
3)資料傳輸
- Leader接收到Producer的資訊并寫入本地Log
- 其他Follower從Leader Pull資訊,并寫入本地log,完成後向Leader發送ACK
- Leader接收到所有Follower資訊,并設定一個HW(High Watermark),然後向Producer發送ACK
2、消費方式及配置設定政策
實際消費資料時Kafka中的消費者——Consumer會以Consumer Group的形式與Topic互動并配置設定對應的Partition。在消費過程中一個Group内的資料不重複,但多個Group之間的資料可重複消費,這也是釋出-訂閱制的特點。
開發人員可以利用這一特點實作在不影響主業務流程的情況下,對業務資料進行實時監控等。
一個Group中包含至少有一個Consumer,一個Topic下也至少包含一個Partiton。一個Consumer Group中的多個Consumer可以并行消費不同的Partition,以此來提高對Kafka資料消費的并行度,進而提高資料處理的速度。但是在消費的過程中,針對于Partition和Consumer數量的不同,會出現各種情況,Kafka針對于不同的情況有相應的配置設定政策,可參考如下:
四、實時開發如何使用Kafka
在實際生産中,實時開發也是以一個消費者組或生産者組的方式去Kafka中消費相應的資料。
在實時采集任務過程中,采集資料源的資料到Kafka,通過設定不同的寫入并發數,可以設定多個Producer向同一個Topic下進行資料寫入,提高并發度和資料讀取效率;同樣,當采集Kafka資料源時,通過設定不同的讀取并發數,可以在一個Group内設定多個Consumer同時對Topic内的資料進行消費。
在實時開發任務中,也可以設定Kafka資料源的并行度,進而根據實際業務需求調整并行度來滿足消費需求。
五、結語
通過今天的介紹,我們了解到Kafka作為典型“釋出-訂閱”形式的消息隊列如何通過幫助使用者臨時存儲流式資料,并通過Consumer Group和Partition的機制實作多并發的讀寫以提高實時開發相關的效率。後續我們還會繼續介紹跟實時開發相關的内容,敬請期待。