Kafka 裏面的信息是如何被消費的?

Kafka 裏面的信息是如何被消費的?

Kafka 裏面的信息是如何被消費的?

攝影:產品經理
跟着產品經理去蘇州吃麪
做爲一個爬蟲工程師,Kafka 對你而言就是一個消息隊列,你只須要掌握如何向裏面寫入數據,以及如何讀取數據就能夠了。

面試

請謹記:使用 Kafka 很容易,但對 Kafka 集羣進行搭建、維護與調優很麻煩。Kafka 集羣須要有專人來維護,不要覺得你能輕易勝任這個工做。」

本文,以及接下來的幾篇針對 Kafka 的文章,咱們面向的對象都是爬蟲工程師或者僅僅須要使用 Kafka 的讀者。關於 Kafka 更深刻的底層細節與核心原理,不在咱們的討論範圍中。爲了解釋方便,文章中對 Kafka 的一些術語會使用一些不太準確但能代表意思的類比。若是你須要在面試中解釋這些術語,還請閱讀Kafka 的官方文檔。數據庫

今天咱們要討論的一個話題是,Kafka 是如何作到,對單個程序的多個進程而言,能持續消費,斷點續傳和並行消費;對多個程序而言又互不影響,各自獨立。ide

一個 Kafka 能夠有多個不一樣的隊列,咱們把這個隊列叫作Topic,假設其中一個隊列以下圖所示:
Kafka 裏面的信息是如何被消費的?
spa

信息從右邊進去,從左邊出來。若是這是Redis 的列表,那麼它彈出一條信息之後,隊列會變成下面這樣:
Kafka 裏面的信息是如何被消費的?
code

最左邊的信息1不見了。因此即便程序在消費了信息1後馬上關閉,再從新打開,程序也會接着從信息2開始消費,不會把信息1重複消費兩次。對象

但我若是有兩個程序呢?程序1讀取每一條數據,再轉存到數據庫。程序2讀取每一條數據,再檢查是否有關鍵詞。這種狀況下,信息1應該能被程序1消費,也能被程序2消費。但上面這種方案顯然是不行的。當程序1消費了信息1,程序2就再也拿不到它了。blog

因此,在 Kafka 裏面,信息會停留在隊列裏面,但對每個程序來講,有一個單獨的記號,來記錄當前消費到了哪一條數據,以下圖所示。
Kafka 裏面的信息是如何被消費的?
教程

當程序1要讀取 Kafka 裏面下一條數據時,Kafka 先把當前位置的標記向右移動一位,把新的這個值返回出來。標記移動與返回這兩個操做合在一塊兒算是一個原子操做,不會出現重複讀取的問題。隊列

程序1與程序2使用的是不一樣的標記,因此各自的標記指向哪一個值,是互不影響的。進程

當增長一個程序3的時候,只須要再加一個標記便可。新的這個標記也不受前兩個標記的影響。

這就實現了在多個不一樣的程序讀取 Kafka 時,各自互不影響。

如今若是你以爲程序1消費太慢了,把程序1同時運行了3次,那麼因爲標記和移位是原子操做,即便你看起來程序是同時去讀取 Kafka,但在內部 Kafka 也會對他們進行「排隊」,從而使得他們返回的結果不重複,不遺漏。

若是你在網上看 Kafka 的教程,你會發現他們提到了一個叫作 Offset 的東西,實際上就是本文所說的各個程序裏面指向當前數據的標記。

你還會看到一個關鍵詞叫作Group,實際上對應到本文的程序1,程序2和程序3。

對同一個隊列,若是多個程序使用不一樣的Group消費,那麼他們讀取的數據就互不干擾。

對同一個隊列,相同 Group 的多個進程在消費數據時,看起來就像是在對 Redis 進行 lpop 操做同樣。

最後,你在網上關於 Kafka 的文章裏面,必定會看到一個詞叫作Paritition或者中文分片。並且你會發現你沒法理解這個東西。

不要緊,忘記它吧。你只須要知道,一個 Topic 有多少個 Partition,那麼你最多能啓動多少個進程讀取同一個 Group。——若是一個Topic有3個Partition,那麼你只能最多開3個進程同時讀相同的 Group。Topic若是有5個Partition,那麼你只能最多開5個進程讀同一個 Group。

下一篇文章,咱們用 Python 來讀寫一下 Kafka。只須要幾行代碼。

Kafka 裏面的信息是如何被消費的?

相關文章
相關標籤/搜索