1. 程式人生 > >Apache Kafka入門教程輕鬆學- Kafka核心概念

Apache Kafka入門教程輕鬆學- Kafka核心概念

本入門教程,涵蓋Kafka核心內容,通過例項和大量圖表,幫助學習者理解,任何問題歡迎留言。

目錄:

本章是學習kafka的核心章節,涵蓋內容比較多,在理解上有一定的難度,需要反覆閱讀理解,才能參透Kafka的設計思想。

1、Kafka叢集結構

在第一章我給出過一個訊息系統通用的結構圖,也就是下圖:

實際上kafka的結構圖是有些區別的,現在我們看下面的圖:

producer和consumer想必大家都很熟悉,一個生產訊息,一個消費掉訊息。這裡就不再做太多解釋。

此圖和第一張圖可以看到有幾個區別:

1、多了zookeeper叢集,通過前幾章的學習我們已經知道kafka是配合zookeeper進行工作的。

2、kafka叢集中可以看到有若干個Broker,其中一個broker是leader,其他的broker是follower

3、consumer外面包裹了一層Consumer group。

我們先講解一下Broker和consumer group的概念,以及Topic。

Broker

一個Borker就是Kafka叢集中的一個例項,或者說是一個服務單元。連線到同一個zookeeper的多個broker例項組成kafka的叢集。在若干個broker中會有一個broker是leader,其餘的broker為follower。leader在叢集啟動時候選舉出來,負責和外部的通訊。當leader死掉的時候,follower們會再次通過選舉,選擇出新的leader,確保叢集的正常工作。

Consumer Group

Kafka和其它訊息系統有一個不一樣的設計,在consumer之上加了一層group。同一個group的consumer可以並行消費同一個topic的訊息,但是同group的consumer,不會重複消費。這就好比多個consumer組成了一個團隊,一起幹活,當然幹活的速度就上來了。group中的consumer是如何配合協調的,其實和topic的分割槽相關聯,後面我們會詳細論述。

如果同一個topic需要被多次消費,可以通過設立多個consumer group來實現。每個group分別消費,互不影響。

通過本節學習,我們從全域性的層面瞭解了kafka的結構,接下來我們會深入到kafka內部,來看看它是怎麼工作的。

Topic

kafka中訊息訂閱和傳送都是基於某個topic。比如有個topic叫做NBA賽事資訊,那麼producer會把NBA賽事資訊的訊息傳送到此topic下面。所有訂閱此topic的consumer將會拉取到此topic下的訊息。Topic就像一個特定主題的收件箱,producer往裡丟,consumer取走。

2、Kafka核心概念簡介

kafka採用分割槽(Partition)的方式,使得消費者能夠做到並行消費,從而大大提高了自己的吞吐能力。同時為了實現高可用,每個分割槽又有若干份副本(Replica),這樣在某個broker掛掉的情況下,資料不會丟失。

接下來我們詳細分析kafka是如何基於Partition和Replica工作的。

分割槽(Partition)

大多數訊息系統,同一個topic下的訊息,儲存在一個佇列。分割槽的概念就是把這個佇列劃分為若干個小佇列,每一個小佇列就是一個分割槽,如下圖:

這樣做的好處是什麼呢?其實從上圖已經可以看出來。無分割槽時,一個topic只有一個消費者在消費這個訊息佇列。採用分割槽後,如果有兩個分割槽,最多兩個消費者同時消費,消費的速度肯定會更快。如果覺得不夠快,可以加到四個分割槽,讓四個消費者並行消費。分割槽的設計大大的提升了kafka的吞吐量!!

我們再結合下圖繼續講解Partition。

此圖包含如下幾個知識點:

1、一個partition只能被同組的一個consumer消費(圖中只會有一個箭頭指向一個partition)

2、同一個組裡的一個consumer可以消費多個partition(圖中第一個consumer消費Partition 0和3)

3、消費效率最高的情況是partition和consumer數量相同。這樣確保每個consumer專職負責一個partition。

4、consumer數量不能大於partition數量。由於第一點的限制,當consumer多餘partition時,就會有consumer閒置。

5、consumer group可以認為是一個訂閱者的叢集,其中的每個consumer負責自己所消費的分割槽

為了加深理解,我舉個吃蘋果的例子。

問題:有一籃子蘋果,你如何把這一籃子蘋果儘可能快的吃完?

辦法一:

我一個人,一個一個蘋果吃,如下圖。這樣顯然很慢,我吃完一個才能拿下一個。

辦法二:

我再找兩個人來一塊吃,第一個人拿走一個去吃,然後第二個人拿一個去吃,接著第三個人拿一個去吃,如此迴圈。速度肯定快了,但是三個人還是會排隊等待。三個人排隊時間可能很短,但是如果叫了100個人幫忙吃呢?會有大量時間消耗在排隊上。

辦法三:

我還是找兩個人來一塊吃,但我把蘋果提前分到三個盤子裡,每人分一個盤子,自己吃自己的,這樣不但能三個人同時吃蘋果,還無須排隊。速度顯然是最快的。

辦法三正是kafka所採用的設計方式,盤子就是partition,每個人就是一個consumer,每個蘋果就是一條message。辦法三每個盤子中蘋果的消費是有序的,而辦法二的消費是完全無序的。

相信通過這個例子你一定能充分理解partition的概念,以及為什麼kafka會如此設計。

關於partition暫時說到這裡,接下來介紹副本。

副本(Replica)

提到副本,肯定就會想到正本。副本是正本的拷貝。在kafka中,正本和副本都稱之為副本(Repalica),但存在leader和follower之分。活躍的稱之為leader,其他的是follower。

每個分割槽的資料都會有多份副本,以此來保證Kafka的高可用。

Topic、partition、replica的關係如下圖:

topic下會劃分多個partition,每個partition都有自己的replica,其中只有一個是leader replica,其餘的是follower replica。

訊息進來的時候會先存入leader replica,然後從leader replica複製到follower replica。只有複製全部完成時,consumer才可以消費此條訊息。這是為了確保意外發生時,資料可以恢復。consumer的消費也是從leader replica讀取的。

由此可見,leader replica做了大量的工作。所以如果不同partition的leader replica在kafka叢集的broker上分佈不均勻,就會造成負載不均衡。

kafka通過輪詢演算法保證leader replica是均勻分佈在多個broker上。如下圖。

可以看到每個partition的leader replica均勻的分佈在三個broker上,follower replica也是均勻分佈的。

關於Replica,有如下知識點:

1、Replica均勻分配在Broker上,同一個partition的replica不會在同一個borker上

2、同一個partition的Replica數量不能多於broker數量。多個replica為了資料安全,一臺server存多個replica沒有意義。server掛掉,上面的副本都要掛掉。

3、分割槽的leader replica均衡分佈在broker上。此時叢集的負載是均衡的。這就叫做分割槽平衡

分割槽平衡是個很重要的概念,接下來我們就來講解分割槽平衡。

分割槽平衡

在講分割槽平衡前,先講幾個概念:

1、AR: assigned replicas,已分配的副本。每個partition都有自己的AR列表,裡面儲存著這個partition最初分配的所有replica。注意AR列表不會變化,除非增加分割槽。

2、PR(優先replica):AR列表中的第一個replica就是優先replica,而且永遠是優先replica。最初,優先replica和leader replica是同一個replica。

3、ISR:in sync replicas,同步副本。每個partition都有自己的ISR列表。ISR是會根據同步情況動態變化的。

最初ISR列表和AR列表是一致的,但由於某個節點死掉,或者某個節點的follower replica落後leader replica太多,那麼該節點就會被從ISR列表中移除。此時,ISR和AR就不再一致

接下來我們通過一個例子來理解分割槽平衡。

1、根據以上資訊,一個擁有3個replica的partition,最初是下圖的樣子。

可以看到AR和ISR保持一致,並且初始時刻,優先副本和leader副本都指向replica 0.

2、接下來,replica 0所在的機器下線了,那麼情況會變成如下圖所示:

可以看到replica 0已經從ISR中移除掉了。同時,由於重新選舉,leader副本變成了replica 1,而優先副本還是replica 0。優先副本是不會改變的。

由於最初時,leader副本在broker均勻分佈,分割槽是平衡的。但此時,由於此partition的leader副本換成了另外一個,所以此時分割槽平衡已經被破壞。

3、replica 0所在的機器修復了,又重新上線,情況如下圖:

可以看到replica 0重新回到ISR列表中,不過此時他沒能恢復leader的身份。只能作為follower當一名小弟。

此時分割槽依舊是不平衡的。那是否意味著分割槽永遠都會不平衡下去呢?不是的。

4、kafka會定時觸發分割槽平衡操作,也可以主動觸發分割槽平衡。這就是所謂的分割槽平衡操作,操作完後如下圖。

可以看到此時leader副本通過選舉,會重新變回來replica 0,因為replica 0是優先副本,其實優先的含義就是選擇leader時被優先選擇。這樣整個分割槽又回到了初始狀態,而初始時,leader副本是均勻分佈的。此時已經分割槽平衡了。

由此可見,分割槽平衡操作就是使leader副本和優先副本保持一致的操作。可以把優先副本理解為分割槽的平衡狀態位,平衡操作就是讓leader副本歸位。

Partition的讀和寫

通過之前的學習,我們知道topic下劃分了多個partition,訊息的生產和消費最終都是發生在partition之上。下圖是一個三個partition的topic的讀寫示意。

我們先看右邊的producer,可以看到寫的時候,採用round-robin演算法,輪詢往每個partition寫入。

而在消費者端,每個consumer都維護一個offset值,指向的是它所消費到的訊息座標。

我們先看group A的三個consumer,他們分別獨立消費不同的三個partition。每個consumer維護了自己的offset。

再結group B,可以看到兩個group是並行消費整個topic,同一條訊息會被不同group消費到。

此處有如下知識點:

1、每個partition都是有序的不可變的。

2、Kafka可以保證partition的消費順序,但不能保證topic消費順序。

3、無論消費與否,保留週期預設兩天(可配置)。

4、每個consumer維護的唯一元資料是offset,代表消費的位置,一般線性向後移動。

5、consumer也可以重置offset到之前的位置,可以以任何順序消費,不一定線性後移。

回顧

本章是理解kafka設計的核心,通過本章學習你應該理解如下知識點:

  1. producer
  2. consumer
  3. consumer group
  4. broker
  5. 分割槽(partition)
  6. 副本(replica)
  7. 分割槽平衡
  8. 訊息讀寫

如果對上面提到的知識點還有不清晰的地方,請再複習,或者找其它學習資料進行學習。

--------------------- 本文來自 稀有氣體 的CSDN 部落格 ,全文地址請點選:https://blog.csdn.net/liyiming2017/article/details/82805479?utm_source=copy