kafka詳解(一)--kafka是什麼及怎麼用

kafka是什麼

在回答這個問題之前,我們需要先了解另一個東西--event streaming。

什麼是event streaming

我覺得,event streaming 是一個動態的概念,它描述了一個個 event ( "something happened" in the world ) 在不同主體間連續地、正確地流動的狀態。(這裏我想搞個動圖的,不過 plantuml 不支持,所以只能靠想象了。。)

zzs_kafka_architecture_01

event source 產生 event,event source 可以是數據庫、傳感器、移動設備、應用程序,等等。

event broker 持久化 event,以備 event sink 可以隨時獲取它們。

event sink 實時或回顧性地從 broker 中獲取 event 進行處理。

有的人可能會問,爲什麼需要 broker,event 從 source 直接流到 sink 不行嗎?當然可以,但是不夠解耦,要麼 event source 需要事先知道誰需要這些 event,要麼 event sink 需要知道 event 從哪裏來。

現在,我們可以在腦子裏想象出 event streaming 的樣子:event 由 source 產生,然後流向 broker,在 broker 被持久化,再流到 sink。並不複雜對吧?

event streaming用來幹嘛

我們可以在很多的應用場景中找到 event streaming 的身影,例如:

  • 實時處理支付、金融交易、客戶訂單等等;

  • 實時跟蹤和監控物流進度;

  • 持續捕獲和分析來自物聯網設備或其他設備的傳感器數據;

  • 不同數據源的數據連接;

  • 作爲數據平臺、事件驅動架構和微服務等的技術基礎;

等等。

kafka是什麼

現在我們回過頭來回答問題:kafka 是什麼?

我認爲,如果說 event streaming 是一種規範的話,那麼 kafka 就是 event streaming 的一種具體實現

kafka的架構

概念視圖

從最上層的抽象看,kafka 由三個部分組成:

zzs_kafka_architecture_02

其中,producer 發佈 event,broker 持久化 even,consumer 訂閱 event。其中,producer 和 consumer 完全解耦,互不知曉。

不過,這是概念視圖,不是物理視圖。具體實現會因爲 source 或 sink 的不同而有所不同。

物理視圖

Producer/Consumer API

當 event source 爲普通應用程序時,可以在程序中引入 Producer API 和 Consumer API 來完成與 broker 的交互。這些 API 涵蓋了大部分主流語言,例如 Java、Scala、Go、Python、C/C++,除此之外,我們也可以直接使用 REST API 調用。

zzs_kafka_architecture_03

Connector

但是,並不是所有 source 或 sink 都能使用 API 的方式,例如,實時捕獲數據庫的更改、文件的更改,從 RabbitMQ 導入導出消息,等等。

這個時候就需要使用 connector 來完成集成。通常情況下,connector 並不需要我們自己開發,kafka 社區爲我們提供了大量的 connector 來滿足我們的使用需求。

zzs_kafka_architecture_04

topic&partition

接下來我們再來補充下 broker 的一些細節。//zzs001

通常情況下,我們的 broker 會接收到很多不同類型的 event ,broker 需要區分它們,以便正確地路由。topic 就發揮了作用,它有點類似文件系統的目錄,而 event 就類似於目錄裏的文件,sink 想要什麼 event,只要找到對應的 topic 就行了。

同一 topic 可以有零個或多個 producer 和 consumer,不同於傳統 MQ,kafka 的 event 消費後並不刪除,爲什麼這麼做呢?這個我們後續的博客會說的。

zzs_kafka_architecture_05

除此之外,一個 topic 會劃分成一個或多個 partition,這些 partition 一般分佈在不同的 broker 實例。producer 發佈的 event 會根據某種策略分配到不同的 partition,這樣做的好處是,consumer 可以同時從多臺 broker 讀取 event,從而大大提高吞吐量。另外,爲了高可用,同一個 partition 還會有多個副本,它們分佈在不同的 broker 實例。

zzs_kafka_architecture_06

需要注意一下,當同一 topic 的 event 被分發到多個 partition 時,寫入和讀取的順序就不能保證了,對於需要嚴格控制順序的 topic,partition 需要設置爲 1。

Streams

kafka 那麼受歡迎,還有一個很重要的原因,就是它提供了流式處理類庫,支持對存儲於Kafka內的數據進行流式處理和分析。這部分內容,我也是剛入門而已,後續博客再好好研究。

zzs_kafka_architecture_07

如何使用kafka

環境說明

kafka:3.2.1

os:CentOS Linux release 8.3.2011

JDK:1.8.0_291

注意,kafka 3.2.1 要求本地環境安裝 Java 8 及以上版本

下載安裝

從 下載頁面下載安裝包。

zzs_kafka_quickstart_01

解壓安裝包。

tar -xzf kafka_2.13-3.2.1.tgz

啓動broker

進入到解壓目錄,我們看看 kafka 的目錄結構。

cd kafka_2.13-3.2.1
ls -al

zzs_kafka_quickstart_02

接下來,我們啓動 broker 的部分,需要按照順序依次啓動 zookeeper 和 kafka server。

先啓動 zookeeper(後續版本可能不再需要 zookeeper)。

bin/zookeeper-server-start.sh config/zookeeper.properties

打開另一個會話,再啓動 kafka server。

bin/kafka-server-start.sh config/server.properties

現在,單機版 broker 已經就緒,我們可以開始使用了。

創建topic

producer 發佈的 event 會持久化在對應的 topic 中,才能路由給正確的 consumer。所以,在讀寫 event 之前,我們需要先創建 topic。

打開另一個會話,執行以下命令。

# 創建topic  zzs001
bin/kafka-topics.sh --create --topic quickstart-events --bootstrap-server localhost:9092
# 查詢topic  
bin/kafka-topics.sh --describe --topic quickstart-events --bootstrap-server localhost:9092

zzs_kafka_quickstart_05

簡單的讀寫event

接下來我們用 kafka 自帶的 console-consumer 和 console-producer 讀寫 event。

使用 console-producer 寫 event 時,我們每輸入一行並回車,就會向 topic 寫入一個 event。

bin/kafka-console-producer.sh --topic quickstart-events --bootstrap-server localhost:9092

zzs_kafka_quickstart_06

寫完之後我們可以按 Ctrl + C 退出。

接着,我們使用 console-consumer 讀 event。可以看到,剛寫的 event 被讀到了。

bin/kafka-console-consumer.sh --topic quickstart-events --from-beginning --bootstrap-server localhost:9092

zzs_kafka_quickstart_07

讀完我們按 Ctrl + C 退出。

我們可以在兩個會話中保持 producer 和 consumer 不退出,當我們在 producer 寫入 event 時, consumer 將實時讀取到。

前面提到過,topic 的 event 會被持久化下來,而且被消費過的 event 並不會刪除。這一點很容易驗證,我們可以再開一個 consumer 來讀取,它還是能讀到被別人讀過的 event。

使用connect導入導出

前面提到過,有的 source 或 sink 需要依賴 connector 來讀寫 event,接下來我們以文件爲例,演示如何從已有文件中將 event 導入 topic,並從 topic 中導出到另一個文件中。

首先我們需要一個可以導入導出文件的 connector,默認情況下,在 kafka 的 libs 目錄就有這樣一個 jar 包--connect-file-3.2.1.jar。我們需要在 connect 的配置中引入這個包。

vi config/connect-standalone.properties

按 i 進入編輯,添加或修改plugin.path=libs/connect-file-3.2.1.jar

按 ESC 後輸入 :wq 保存並退出。除此之外,這個文件還可以用來配置需要連接哪個 broker,以及 event 的序列化方式等。

zzs_kafka_quickstart_09

然後,我們創建一個 test.txt 作爲 event source,並寫入 event。

echo -e "foo\nbar" > test.txt

zzs_kafka_quickstart_10

現在我們先啓動 event source 的 connector,將 test.txt 的 event 寫入名爲 connect-test 的 topic。config/connect-file-source.properties 已經配置好了connector 名稱、event source 的文件、topic,等等。

bin/connect-standalone.sh config/connect-standalone.properties config/connect-file-source.properties

執行片刻後我們可以按 Ctrl + C 退出。

這時,我們可以先通過 consumer-console 查看 topic 上是否有這些 event。可以看到,event 已經成功導入,至於格式爲什麼是這樣的,這個以後再說明。

bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic connect-test --from-beginning

zzs_kafka_quickstart_14

現在我們啓動 event sink 的 connector,將 topic 的 event 導入到 test.sink.txt。connect-file-sink.properties 已經配置好了connector 名稱、event source 的文件、topic,等等 。

bin/connect-standalone.sh config/connect-standalone.properties  config/connect-file-sink.properties

執行片刻後我們可以按 Ctrl + C 退出。

這時查看 test.sink.txt,可以看到 event 成功導出。

zzs_kafka_quickstart_13

和前面一樣,這裏我們也可以保持 event source 和 event sink 的 connector 不退出,測試實時生產和消費 event。

使用streams處理

這部分內容後續再補充。

停止

走到這一步,我們已經完成了 kafka 的入門學習。

接下來,我們可以通過以下步驟關閉 kafka。

  1. 如果 producer 或 consumer 還在運行,Ctrl + C 退出;

  2. Ctrl + C 退出 kafka server;

  3. Ctrl + C 退出 zookeeper;

如果想清除 kafka 的數據,包括我們創建的 topic 和 event、日誌等,執行以下命令:

rm -rf /tmp/kafka-logs /tmp/zookeeper  /tmp/connect.offsets

結語

以上內容是最近學習 kafka 的一些思考和總結(主要參考官方文檔),如有錯誤,歡迎指正。

任何的事物,都可以被更簡單、更連貫、更系統地瞭解。希望我的文章能夠幫到你。

最後,感謝閱讀。

參考資料

Apache Kafka 官方文檔

相關源碼請移步:https://github.com/ZhangZiSheng001/kafka-demo

本文爲原創文章,轉載請附上原文出處鏈接:https://www.cnblogs.com/ZhangZiSheng001/p/16641755.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章