Kafka應該怎麼用,那麼多API,怎麼入手,快到碗裡來

Kafka 是一頭值得研究的野獸。儘管隨著時間的推移,Kafka 的核心已經相當穩定,但圍繞 Kafka 的框架卻在迅速發展。

幾年前,Kafka 很容易理解:Producer 和 Consumer。現在,我們還有 Kafka Connect、Kafka Streams 和 KSQL。它們是要取代 Producer 或 Consumer API,還是對它們的補充?本文將詳細說明。

Kafka應該怎麼用,那麼多API,怎麼入手,快到碗裡來

一個簡單的示意圖

選擇合適的 Kafka API

我把 Apache Kafka 中的工作負載歸納成 5 類,在我看來, 每一種對應一種特定的 API:

Kafka Producer API:

應用程式直接生成資料(如點選流、日誌、物聯網);

Kafka Connect Source API:

應用程式連線我們無法控制的資料儲存和 Kafka(如 CDC、Postgres、MongoDB、Twitter、REST API);

Kafka Streams API / KSQL

:從 Kafka 消費並把生成的資料傳回 Kafka 的應用程式,也稱為流處理。如果你認為你只需要編寫類似 SQL 的實時任務,則可以使用 KSQL;如果你認為你需要編寫複雜的任務邏輯,則可以使用 Kafka Streams API。

Kafka Consumer API:

讀取流並以此為依據實時執行動作(如傳送電子郵件);

Kafka Connect Sink API:

讀取流,並將其儲存到目標儲存(如 Kafka 到 S3、Kafka 到 HDFS、Kafka 到 PostgreSQL、Kafka 到 MongoDB 等)。

你可能想做一些和上面說的都不一樣的事情,Kafka 也支援你這麼做。例如,如果你想要根據自己的需求編寫大量定製化程式碼,Kafka Consumer 和 Kafka Connect Sink API 是可以互換的。

總的來說,上面的指導原則應該可以幫助你以最少的程式碼和挫折來實現最高效的工作流。

Kafka Producer API

優點

Kafka Producer API 使用起來非常簡單:傳送資料,這是非同步的,會有一個回撥。這非常適合直接傳送資料流的應用程式,比如日誌、點選流、物聯網。

這種 API 經常和代理一起使用。

侷限

Kafka Producer API 可以擴充套件,你可以以此為基礎做更多的事情,但是,這需要工程師編寫大量的附加邏輯。我發現,人們犯的最大錯誤是試圖使用 Producer API 在資料庫和 Kafka 之間執行 ETL。以下是一些不容易做到的事情:

如何跟蹤源偏移?(即如果 Producer 停止了,該如何恰當恢復)

如何在多個 Producer 之間分配 ETL 工作負載?為此,我們最好使用 Kafka Connect Source API。

Kafka Connect Source API

優點

Kafka Connect Source API 是一個構建在 Producer API 之上的完整框架。它主要是為了讓開發人員能夠有一個更好的 API:1)用於 Producer 任務分發以進行並行處理,2)提供 Producer 恢復的簡單機制。最後一個好處是提供了各種各樣的聯結器,你現在可以利用它們從大多數源傳輸資料,而無需編寫一行程式碼。

侷限

如果你未能為自己的源找到一個可用的源聯結器,原因是在你的的環境中使用了一個專有的系統,那麼你將不得不編寫自己的源聯結器。編寫自己的源聯結器實際上還算輕鬆,但除錯它就不那麼令人愉快了。

Kafka Consumer API

優點

Kafka Consumer API 非常簡單,它使用 Consumer 群組,所以主題可以並行消費。儘管你需要小心處理一些事情,比如偏移管理和提交,以及重新平衡和冪等約束,但是它們非常容易編寫。對於任何無狀態的工作負載,它們都是完美的選擇。

侷限

當你執行某種 ETL 時,Kafka Connect Sink 更適合,因為它們使你不必針對外部資料來源編寫一些複雜的邏輯。

Kafka Connect Sink API

優點

與 Kafka Connect Source API 類似,Kafka Connect Sink API 允許你利用現有的 Kafka 聯結器生態系統來執行流 ETL,而無需編寫一行程式碼。Kafka Connect Sink API 是構建在 Consumer API 之上的,但是看起來和它沒有什麼不同。

侷限

如果你要編寫的資料接收器還沒有可用的聯結器,則必須編寫 Kafka Connect Sink(如果你願意,也可以是消費者),除錯過程可能會稍微複雜一些。

Kafka Streams API

優點

如果你想要進入流處理的世界,即實時讀取來自 Kafka 的資料,並在處理之後將其寫回 Kafka,那麼,如果你把 Kafka Consumer API 和 Kafka Producer API 連結在一起使用的話,你很可能陷入麻煩之中。值得慶幸的是,Kafka 專案現在提供了 Kafka Streams API (可用於 Java 和 Scala),讓你可以編寫高階 DSL(類似於函數語言程式設計 / Apache Spark 型別的程式)或低階 API(和 Apache Storm 更為相似)。使用 Kafka Streams API 確實需要編寫程式碼,但完全隱藏了維護生產者和消費者的複雜性,使你可以專注於流處理器的邏輯。它還具有連線、聚合和只執行一次處理的特性。

侷限

你將不得不編寫一些程式碼,這可能會變得非常混亂和複雜。直到最近,還很難對 Kafka Streams 應用程式進行單元測試,但現在可以使用 test-utils 庫來實現。最後,儘管 Kafka Streams 看起來很簡單,但它實際上是後臺的一頭野獸,它會建立狀態儲存,很可能是以 Kafka 主題為基礎。這意味著,雖然作為額外的好處,你將擁有“無狀態”和完全彈性的應用程式,但基於拓撲的複雜性,Kafka 叢集可能不得不開始處理更多的訊息。

KSQL

優點

KSQL 不是 Kafka API 的直接組成部分,而是 Kafka Streams 的包裝器。在這裡仍然值得一提。儘管 Kafka Streams 使你可以編寫一些複雜的拓撲,但那需要一些豐富的程式設計知識,而且可能難以閱讀,尤其是對於新手來說。KSQL 希望透過提供一個 SQL 語義(非 ANSI)來抽象這種複雜性,該語義與你今天已經瞭解的內容非常接近。我不得不承認,它非常具有吸引力,使你可以輕鬆編寫流處理器。記住,這不是批處理 SQL,而是流 SQL,因此會出現一些警告。

侷限

如果你想要進行復雜的轉換、分解陣列或需要一個尚未可用的特性,有時你必須回到 Kafka Streams。這個庫的發展非常迅速,所以我預計功能缺口可以很快被填補。

總 結

我希望本文能夠幫助你理解哪種 Kafka API 適合你的場景,以及為什麼。