Kafka基礎概念介紹

在之前的一篇文章當中介紹了kafka在windows上面的安裝以及簡單的使用命令,windows 系統 上啓動kafka

這篇主要是來介紹以下kafka當中的一些基本概念,先對kafka有一個感性的認識。

消息隊列的基本框架是

                   生產者-------》消息隊列《----------消費者

生產者(Producer)

   生產者就是消息的創造者,主要工作就是源源不斷的產生消息,然後將其發送給消息隊列,生產者可以發送各種消息給消息隊列。

消費者(Consumer)

    消費者就是不斷地從消息隊列當中獲取消息進行處理。

代理(Broker)

    在消息隊列模型當中,Broker所指的就是消息隊列本身,在kafka當中broker指的就是kafka Server這臺服務,我們可以把部署了KafkaServer的這臺機器看做是一個Broker。從流程上來說,生產者將消息發送個broker, 消費者從broker當中獲取消息。

主題(Topic)

    主題是一個邏輯上的一個概念,主要是用來對消息進行一個劃分,多個生產者可以向一個主題當中發送消息,同時也可以有多個消費者來消費同一個主題當中的消息。Kafka當中每個消息都屬於一個主題,每個主題下面可以有任意數量的消息。

消息(Record)

   消息是整個消息隊列當中最爲基本的一個概念,也是最爲原子的概念。它指的是生產者發送與消費者拉取的一個原子事務。一個消息需要關聯到一個具體的topic上。消息是由一串字符串所構成,其中主要有key和value兩個部分,key和value本質上都是字節數組。當我們在發送消息時,可以省去掉key,直接發送value, 比如上篇文章當中給出的簡單例子,我們發送的消息其實都只是value。key的主要作用是根據一定的策略,將消息發送到指定的分區,這樣可以保證同一個key值的消息全部都寫入到一個分區當中。

集羣(Cluster)

     集羣指的是多個broker構成的一個整體,對外提供一定的服務,比較類似我們在部署應用的時候,都會採用集羣的方式進行部署。集羣主要是爲了保證其中一個broker掛了之後,kafka還能正常使用。集羣當中的各個broker之間通過心跳的方式來確定其他機器是否存活。

控制器(Controller)

    控制器是集羣當中的概念,每個集羣都會選擇一個broker來擔任控制器的角色。在一個集羣當中,控制器這臺broker會控制其他的broker實現相應的功能。控制器主要是負責kafka分區狀態,管理每個分區的副本狀態,監聽zookeeper中數據的變化並作出相應的反饋。所有的broker都會監聽Controller的狀態,當controller出現故障時,會選舉一個新的broker作爲controller。

消費者組(Consumer Group)

    kafka當中多個消費者可以組成一個消費者組。消費者組的主要作用是用來實現單播和廣播。一個消費者組可以確保其訂閱的topic每個分區只能被從屬於該消費者組當中的一個消費者所消費。如果不同的消費者組訂閱了同一個topic,那麼這些消費者組之間是彼此獨立的,不會受到干擾。如果我們希望一個消息,被多個消費者所消費,可以將這些消費者放在不同的消費者組中,這個就是廣播。如果一個消息只能被一個消費者所消費,那麼可以將這些消費者放在同一個組當中,這就是單播。舉個例子,在我們實際開發當中,一個應用會採用微服務的形式分成很多個小的應用,比如人員管理系統,消費管理系統,倉庫管理系統,每個系統爲了保證其穩定性,都設置了多個實例,即多個應用部署,假設現在人員管理系統添加了一個新的人員信息,需要把這個信息作爲消息,發送給消費管理系統和倉庫管理系統,我們可以把消費管理系統的多個實例,放在一個消費者組當中,這樣一個人員信息只會被消費管理系統當中的其中一個應用所獲取,倉庫管理系統當中的多個實例又是在另外一個消費者組當中,因此倉庫管理系統當中只能有一個實例拉取到新增的人員信息然後進行處理。而倉庫管理系統和消費管理系統屬於不同的消費者組,因此都可以獲取到人員信息。

分區(Partition)

   每個主題都可以被劃分成多個分區(每個主題至少有一個分區),在同一個主題下,不同分區所包含的內容是不同的,每個消息再被添加到分區當中時,都會被分配一個偏移量(offset),它是消息在分區當中的唯一編號,kafka是通過offset來確保一個分區內的消息順序的,offset的順序並不跨越分區,也就是說,在一個分區內消息是順序的,在不同的分區之間,kafka並不保證消息的順序。以下是主題和分區之間的關係

 

上圖當中每個分區內部是有序的,而分區之間是無序的。基於這樣的設計,kafka當中的消息不會隨着分區數量的增多而產生損耗,因此存儲長時間的數據也沒有影響。

kafka當中的消息記錄是存儲在磁盤上的,通過爲每個消息分配offset,就可以保證消息的順序性,當然消息在磁盤上是有保留時間的,過了這個時間,消息就會被丟棄掉,可以通過修改server.properties文件當中log.retention.hours=168,保留七天,修改後重啓生效。

分區的實現:

分區中的消息數據是保存在日誌文件當中的,分區在邏輯上對應一個日誌,當生產者將消息寫入到分區當中時,實際上是寫入到了分區對應的日誌中。而日誌可以看做是一個邏輯上的概念,對應與磁盤上的一個目錄,一個日誌由多個segment構成,每個Segment對應一個索引文件和日誌文件。

分區的作用:

1、藉助於分區,可以實現kafka的水平擴展,我們可以通過分區,將同一個主題下的消息保存在不同的kafka server上,當機器的運行能力不足時,只需要增加機器就可以了,在新的機器上創建分區,就可以實現水平擴展。

2、分區可以實現並行處理能力,當一個主題所發送的消息給該主題的所擁有的不同分區中,這樣消息就可以實現並行發送和處理,由多個分區來接受信息。

分區的數據存儲在server.properties文件中,配置的logs.dir路徑下,如果一個主題下存在多個分區,那麼每個分區就會對應一個目錄,其目錄的命名規則是topic+index, index是從0開始。

每個partion當中並不是由一個文件所構成的,因爲隨着消息數量的增加,如果分區當中的消息都保存在一個文件當中,顯然是不夠用的,kafka採用的是rolling log,也就是當分區當中的消息數量達到一定程度後,消息文件會進行分割,新的消息會被寫到新的文件當中,而這一個個新的文件就叫做segment.

分割分區文件夾下面包含的文件如下

1、0000000000000.index: 這個文件是segment文件的索引文件,他與00000000000.log文件是成對出現的。

2、0000000000000.log: 這是segment文件的數據文件,用於存儲實際的消息,該文件是二進制格式的,segment文件的命名格式是,分區的第一個segment從0開始,後續每個segment的文件名爲上一個segment文件最後一個消息的offset值。沒有數據就用0填充。

3、00000000000000.timeindex:該文件是一個基於日期的索引文件,主要是用在根據日期和時間來找尋消息的場景下,當然我們設置的文件過期時間也會基於這個日期的索引文件來確定哪些是過期的消息

4、leader-epoch-checkpoint : 是一個leader的緩存文件。