Kafka應用實踐與生態整合

哥不是小蘿莉發表於2019-05-26

1.前言

Apache Kafka發展至今,已經是一個很成熟的訊息佇列元件了,也是大資料生態圈中不可或缺的一員。Apache Kafka社群非常的活躍,通過社群成員不斷的貢獻程式碼和迭代專案,使得Apache Kafka功能越發豐富、效能越發穩定,截止本篇部落格Apache Kafka釋出了V2.2.0版本。

那麼,今天就來聊一聊Kafka應用實踐與生態整合的相關內容。

2.如何知道Kafka是否適合你?

專案立項時,會做技術調研,那麼如何知道你選擇的Kafka技術是否能夠滿足你?據Confluent公司調研報告可知,Apache Kafka在過去幾年中在功能和覆蓋範圍方面取得了很大成就。它被財富500強中的三分之一用於生產,包括全球十大銀行中的七家,十大保險公司中的八家,以及美國十大電信公司中的九家。接下來,為大家介紹Kafka示例來幫助大家瞭解常見的使用模式。並且希望大家能找到與自己的工作流程有交集的地方,這樣大家就可以開始利用Kafka的強大功能了。

下面讓先來看看Kafka提供的兩個核心功能:

2.1 訊息系統

訊息系統常見的兩種模式:

  • 佇列:佇列消費者充當了工作組的角色,每條訊息記錄只傳遞給一個工作程式,從而有效的劃分工作流程;
  • 釋出與訂閱:訂閱者通常是彼此獨立的,每個訂閱者都可以獲得每條訊息的副本。

這兩種模式都是有效和實用的,通過佇列將工作內容分開,用於容錯和擴充套件;釋出與訂閱能夠允許多租戶,來使系統解耦。而Apache Kafka的有點之一在於它將佇列、釋出與訂閱結合到了一個強大的訊息系統中。

2.2 流處理

Apache Kafka擁有強大,可擴充套件的訊息系統,只需要一種簡單的方法來處理訊息流。而在Kafka中,Stream API提供這一功能,它是一個Java客戶端類庫,提供比Producer和Consumer更高階別的抽象API。

這使得它使用起來非常的方便:

  • 無狀態操作,例如過濾和轉換流訊息;
  • 有狀態操作,例如時間視窗上的連線和聚合。

Stream API處理訊息的序列化與反序列化,同時維護有狀態操作所需要的狀態。

2.3 典型的Kafka案例

  • 旅遊行業:例如,在一個旅遊網站,酒店和航班的價格是一直在變化的,系統的一些元件(價格告警、分析等)需要了解這些變化。你在Kafka的Topic上釋出更改,並且需要通知的每個元件都充當一個消費者。每個消費者應用所組成的節點形成一個消費者組。給消費者組所消費的Topic的傳送訊息動態記錄,這樣每個消費者均可獲取訊息記錄,同時每個消費者內能夠有效的劃分工作內容。
  • 使用者分析:頁面檢視、搜尋、使用者行為分析等,這些實際上是Kafka在LinkedIn設計的原始初衷。使用者點選網站活動內容,每個活動型別均有一個Topic,可以實時的反饋,以便深入瞭解使用者參與度、下載量、頁面流量等。
  • GPS:例如,能夠實時獲取智慧手機裝置的位置資料,並且希望能夠實時處理這些資料來顯示車輛路徑、行駛距離等。傳入資料到Kafka的Topic中,並使用Stream API來進行處理。當需要在特定時間段內提取和處理給定使用者的所有位置資料時,使用視窗進行狀態處理會有不錯的效果。

3.Kafka的內部儲存工作原理是什麼?

如何你確定了Kafka技術適合你當前的專案,滿足你的業務需求。你可能會很好奇,Kafka的內部儲存工作原理是什麼呢?接下來,將給大家分析Kafka是如何儲存其資料的。

3.1 Kafka儲存單元是分割槽

Topic中的分割槽是有序寫入的,且不可變的訊息序列。分割槽不能跨多個Broker或者多個磁碟來進行分割。

3.2 保留策略來管理Topic中訊息

在你建立的Topic中,你可以指定保留多少資料或者保留多長時間的資料,然後Kafka會按照順序來清除這些訊息(不管訊息是否有被使用)。

3.3 分割槽片段

Kafka需要定期查詢磁碟上待清除的資料,對於分割槽訊息單個非常長的檔案,該操作會很慢並且容易出錯。為了解決這個問題,Kafka實行了分割槽分片策略。當Kafka將訊息寫入分割槽時,它會寫入到一個片段,如果該片段到達閥值,則會新開一個新的片段來寫入。片段以偏移量來命名,片段的偏移量是大於前一個片段的偏移量且小於或者等於當前片段中的偏移量。

3.4 片段日誌是儲存訊息的位置

每條訊息都包含值、偏移量、時間戳、主鍵(KEY)、訊息大小、壓縮編解碼器、校驗、以及訊息格式的版本。磁碟上的資料格式與Broker通過網路從Producer端接收的格式完全相同,然後由Consumer去獲取資料,這使得Kafka能夠通過零拷貝技術有效的傳輸資料。

3.5 片段索引將訊息偏移量對映到它們在日誌中的位置

索引檔案是記憶體對映的,偏移量查詢時使用二進位制搜尋來查詢小於或等於最近的目標偏移量。索引檔案由8個位元組組成,4個位元組用於儲存基本偏移量,另外4個位元組來儲存位置。

3.6 Kafka將壓縮的訊息包裝在一起

傳送壓縮訊息的Producer端會將壓縮批處理,並將其作為包裝訊息的有效負載傳送。和之前一樣,磁碟上的資料與Broker通過網路從Producer端接收併傳送給其Consumer的資料完全相同。 

3.7 Kafka內部儲存工作原理小結

  • Kafka的儲存單元是分割槽;
  • 分割槽通過片段來進行分割;
  • 片段包含兩個檔案:索引和日誌檔案;
  • 索引將每個偏移量對映到它們所在日誌中的訊息位置,用於查詢訊息;
  • 壓縮訊息批處理作為包裝訊息的有效負載;
  • 儲存在磁碟上的資料與Broker通過網路從Producer端接收併發給Consumer的資料相同。

4.Kafka API之間的選擇與競爭

Kafka的核心儘管在一段時間內保持相對的穩定,但是Kafka生態圈然後在快速的發展。最初的Kafka,包含Producer和Consumer,很容易理解。現在Kafka處理Producer和Consumer,還有Kafka Connect、Kafka Streams、以及KSQL。 

4.1 如何正確的選擇Kafka API

  • Kafka Producer API:應用直接生成資料,例如移動裝置、PC、其他硬體等。
  • Kafka Connect Source API:應用程式橋接在我們無法控制的資料儲存介質,例如MongoDB、ElasticSearch、RESTAPI等。
  • Kafka Streams API/KSQL:如果希望像SQL一樣操作實時流資料,可以通過KSQL來完成;如果需要編寫複雜的業務邏輯,可以使用Kafka Streams API來完成。
  • Kafka Consumer API:直接讀取流資料,並對其執行實時操作,例如推送商品促銷活動、傳送郵件、獲取遊戲行為等。
  • Kafka Connect Sink API:讀取實時流並將其儲存到目標介質中,例如Kafka到S3、Kafka到HDFS、Kafka到HBase等。

選擇不同的API來實現不同的業務需求,例如,如果希望為實現的需求編寫大量的自定義程式碼,Kafka Consumer API和Kafka Connect Sink API完全是可以互換的。總而言之,上述API可以幫助你在實際的業務中以最少的程式碼量來實現最有效的工作流程。

4.2 各個API的優勢和侷限

4.2.1 Kafka Producer API

  • 優勢: Kafka Producer API使用起來非常的簡單,非同步傳送資料,獲取回撥結果。非常適合直接傳送資料流的應用程式,例如日誌、點選流、物聯網等。
  • 侷限:可以擴充套件和構建Kafka Producer API以便執行更多的操作,但是這需要開發人員編寫更多的附加邏輯。例如,試圖使用Kafka Producer API在資料庫和Kafka之間執行ETL操作時,如何跟蹤偏移量(即當Producer端停止後,如何正確恢復你的Producer應用程式)?、如何在若干個Producer之間分配ETL的負載?這種情況,我們使用Kafka Connect Source API會更好一些。

4.2.2 Kafka Connect Source API

  • 優勢:Kafka Connect Source API是一個構建在Kafka Producer API之上的完整框架。它的構建是為了讓開發人員能夠獲得更好的API,以便為並行處理生成並分配任務。另外,可以使用各種各樣的聯結器,利用這些聯結器來處理大多數資料介質,且無需編寫任何程式碼。
  • 侷限:適配的資料來源聯結器均是專屬的,如果你當前的資料來源在已有的聯結器中不包含,需要自行編寫聯結器來進行適配。

4.2.3 Kafka Consumer API

  • 優勢:Kafka Consumer API非常簡單,可以使用Consumer Groups,因此可以並行使用Topic。新版本的Kafka(V2.2.0)對於偏移量的管理和提交、Balance、冪等性等無需開發者關心。
  • 侷限:在ETL場景中,Kafka Connect Sink更加合適,因為它們會避免針對外部資料來源編寫複雜的邏輯。

4.2.4 Kafka Connect Sink API

  • 優勢:與Kafka Connect Source API類似,Kafka Connect Sink API允許利用現有的Kafka聯結器的生態系統來執行流式ETL,且無需編寫任何程式碼。Kafka Connect Sink API建立在Kafka Consumer API的基礎之上,但是與它有所不同。
  • 侷限:如果寫入的資料來源沒有可用的介面卡,那麼需要自行編寫Kafka Connect聯結器,並且除錯過程會有些複雜。

4.2.5 Kafka Streams API

  • 優勢:對於流處理場景,Kafka中附帶Kafka Streams API,並且能夠編寫高階DSL(類似於函數語言程式設計或者Spark型別的程式)或偏底層的API(類似於Storm)。Kafka Streams API完全隱藏了Producer和Consumer的複雜性,讓開發者更加專注於流處理的邏輯實現上。同時,它還具有連線、聚合、一次性處理等功能。
  • 侷限:使用Kafka Streams API會讓編碼門檻提高,同時也可能讓你業務邏輯變得複雜。

4.2.6 KSQL

  • 優勢:KSQL不是Kafka API的直接組成部分,而是Kafka Streams之上的包裝器。這裡還是值得一說的,雖然Kafka Streams允許編寫一些複雜的Topology,但它還是需要一些實質性的程式設計知識,尤其是新手來說。KSQL希望通過提供與現有的SQL語義類似來抽象出這種複雜性。對於開發者來說,KSQL是非常具有誘惑力的,它使得流處理器變得輕而易舉。
  • 侷限:對於複雜的業務場景,對資料進行復雜的轉換操作,或一些特定的需求,可能還是需要使用Kafka Streams來完成。

5.Kafka與Kubernetes結合是否效率更高?

5.1 介紹

Kubernetes是Google開源的一個容器編排引擎,它支援自動化部署、大規模可伸縮、應用容器化管理。Kubernetes旨在執行無狀態工作負載,這些工作負載通常採用微服務架構形式,輕量級、水平擴充套件。而Kafka的本質上是一個分散式的儲存介質,這意味著你在使用時必需處理狀態,它比微服務更重要。儘管Kubernetes支援有狀態的工作負載,但還是需要謹慎使用。

那麼,應該在Kubernetes上執行Kafka嗎?如何讓Kafka和Kubernetes互相補充,以及如何避免可能遇到的“坑”?

5.2 基礎指標

  • 程式:Kafka Broker對CPU很友好,TLS的引入可能會產生一些開銷。Kafka Client如果使用加密會需要更多的CPU,但是這並不會影響Broker。
  • 記憶體:Kafka Broker的JVM通常可以設定為4GB-8GB之間,但是由於Kafka大量使用了頁面快取,因此還是需要有足夠的系統記憶體。在Kubernetes中,相應的設定容器資源限制和請求。
  • 儲存:容器中的儲存是暫時的,重啟後資料將會丟失,但是可以對Kafka資料使用空目錄卷。因此,需要使用持久化儲存,儲存必須是非本地的,以便Kubernetes在重啟後或重新定位後更加靈活的選擇另一個節點。
  • 網路:與大多數分散式系統一樣,Kafka效能在很大程度上取決於低網路延遲和高頻寬。建議不要把所有的Broker放在同一個節點,因為這樣會降低可用性。如果Kubernetes節點出現故障,那麼整個Kafka叢集都會出現故障。

5.3 效能

安裝Kafka之前,做POC測試是非常重要的。這樣做的好處是,在遇到有關效能瓶頸問題時,可以提供幫助。而Kafka附帶了兩個POC測試工具,它們分別是:kafka-producer-perf-test.sh和kafka-consumer-perf-test.sh。

  • 監控:監控Kafka指標是非常有必要的,能夠讓我們及時的掌握Kafka、Zookeeper叢集的健康狀態,例如使用Kafka Eagle來監控和管理Kafka Topic(http://www.kafka-eagle.org/)。
  • 日誌:日誌是一個比較關鍵的部分,確保Kafka安裝中所有的容器都記錄到stdout和stderr中,並確保Kubernetes叢集日誌能集中管理,例如輸送到ElasticSearch。
  • 動態更新:StatefulSets支援自動更新,RollingUpdate策略將一次更新一個Kafka Pod,來實現零停機維護,這也是Kubernetes的優勢之一。
  • 擴容:Kubernetes可以很容易的將Pod縮放到一定數量的副本,這意味著可以宣告性的定義所需數量的Kafka Broker。
  • 備份&還原:Kafka部署在Kubernetes中,這樣Kafka的可用性就取決於Kubernetes的可用性,如果Kubernetes叢集出現故障,那麼Kafka的可用性就會下降,同時,也會出現資料丟失的風險,因此需要做好資料備份策略,例如MirrorMaker,或是S3進行連線備份。

5.4 對於Kubernetes的選擇

對於中小型的Kafka叢集,將Kafka部署到Kubernetes是一個不錯的選擇,因為它提供了更大的靈活性、且簡化了操作。如果在延遲或吞吐量方面有較高的功能性要求,獨立部署的方式可能會更好。

6.總結

本篇部落格,介紹了Kafka應用實踐與生態整合,通過閱讀本篇部落格的內容,大家可以參考本篇部落格的內容,來做出合理、有效的選擇。

7.結束語

這篇部落格就和大家分享到這裡,如果大家在研究學習的過程當中有什麼問題,可以加群進行討論或傳送郵件給我,我會盡我所能為您解答,與君共勉!

另外,博主出書了《Kafka並不難學》和《Hadoop大資料探勘從入門到進階實戰》,喜歡的朋友或同學, 可以在公告欄那裡點選購買連結購買博主的書進行學習,在此感謝大家的支援。關注下面公眾號,根據提示,可免費獲取書籍的教學視訊。

相關文章