Kafka架構總結以及常見的面試題總結

kafka名詞說明

分佈式 高吞吐量 消息系統

producer:生產者

consumer:消費者

broker:機器,節點

controller:kafka服務器的主節點 負責管理元數據(zk存儲一份)

follower:kafka服務器的從節點 (同步元數據)

topic:主題。類似於關係型數據庫中的表

partition:一個主題可以有多個分區

replica:副本,爲了保證數據安全,每個partition可以設置多個副本(leader replica和slave replica)

message:消息 存放在partition裏

offset:偏移量 消費者的消費進度

 

NIO:同步非阻塞,服務器實現模式爲一個請求一個線程,即客戶端發送的連接請求都會註冊到多路複用器上,多路複用器輪詢到連接有I/O請求時才啓動一個線程進行處理

reactor

 

跳錶索引 空間換時間 加快消息所在文件查找

 

producer端高性能:批處理、內存池、封裝同一服務器請求

批處理是消息達到16K或者默認0ms發送一批次 batch.size linger.ms

consumer

同一消費者組內部是P2P模式,一個消息只能被同一個消費者組的一個消費者消費

不同組是發佈訂閱模式

0.10後偏移量存儲方式由zk改爲kafka自身的topic 名字爲__consumer_offsets-0到49默認50分區

zk不適合高併發

如何通過offset查找Message

例如,讀取offset=368776的Message,需要通過如下兩個步驟。

第一步:查找Segment File.

00000000000000000000.index表示最開始的文件,其實偏移量(offset)爲0;第二個文件00000000000000368769.index的其實偏移量爲368770(368769+1),依次類推。以其實偏移量命名並排序這些文件,只要根據offset**二分查找**文件列表,就可以快速定位到具體文件。

  當offset=368776時,定位到00000000000000368769.index|log。

第二步:通過Segment File 查找Message。

  通過第一步定位到Segment File,當offset=368776時,依次定位到00000000000000368769.index的元數據物理位置和00000000000000368769.log的物理偏移地址,然後再通過00000000000000368769.log順序查找,知道offset=368776爲止。

  Segment Index File採取稀疏索引存儲方式,可以減少索引文件大小,通過Linux mmap接口可以直接進行內存操作。稀疏索引爲數據文件的每個對應Message設置一個元數據指針,它比稠密索引節省了更多的存儲空間,但查找起來需要消耗更多的時間。

 

kafka元數據刷新時間默認5min

 

生產者發送數據流程

消息封裝成ProducerRecord

序列化

消息計算分區(帶key爲hash,不帶爲輪詢;與broker通信獲取元數據信息)

將消息放到RecordAccumulator(緩存默認32M)

啓動一個Sender線程,去緩存中取消息,封裝成批次(默認16K)

該線程將批次數據發送到broker

1

2

RecordAccmulator 原理

 

ISR:副本同步隊列

AR:所有副本

isr由leader負責維護,follower從leader同步數據有一定的延遲,如果某個follower超過該閾值沒有完成同步,leader就會把該follower從isr中剔除,放到osr中,

osr+isr = ar

kafka中的broker 是幹什麼的

broker 是消息的代理,Producers往Brokers裏面的指定Topic中寫消息,Consumers從Brokers裏面拉取指定Topic的消息,然後進行業務處理,broker在中間起到一個代理保存消息的中轉站。

producer如何優化速度:

增加線程

提高 batch.size

增加更多 producer 實例

增加 partition 數

設置 acks=-1 時,如果延遲增大:可以增大 num.replica.fetchers(follower 同步數據的線程數)來調解;

跨數據中心的傳輸:增加 socket 緩衝區設置以及 OS tcp 緩衝區設置。

 

消費者分區分配策略

range

range策略是基於每個主題的 對於每個主題,我們以數字順序排列可用分區,以字典順序排列消費者。然後,將分區數量除以消費者總數,以確定分配給每個消費者的分區數量。如果沒有平均劃分(PS:除不盡),那麼最初的幾個消費者將有一個額外的分區。

輪詢

輪詢分配策略是基於所有可用的消費者和所有可用的分區的

與前面的range策略最大的不同就是它不再侷限於某個主題

如果所有的消費者實例的訂閱都是相同的,那麼這樣最好了,可用統一分配,均衡分配

 

丟數據場景:

ack=0 沒有消息確認,

ack=1 leader收到消息即發送ack,此時如果isr中的follower還沒同步leader,leader就出問題,這部分數據就回丟失

ack=-1 等待所有follower同步完數據後,再發送ack,延時高,數據安全性最高,也會出現丟失數據的情況:如果isr中只有leader一臺機器時,相當於ack=1的時候

另一個是使用高級消費者的時候消費者讀完數據就提交offset,但數據還沒處理完就掛掉了,此時重新啓動後上一部分數據就不能再消費(使用低級消費者)

 

數據重複場景:

cks = -1 的情況下,數據發送到 leader 後 ,部分 ISR 的副本同步,leader 此時掛掉。比如 follower1 和 follower2 都有可能變成新的 leader, producer 端會得到返回異常,producer 端會重新發送數據,數據可能會重複

 

另外, 在高階消費者中,offset 採用自動提交的方式, 自動提交時,假設 1s 提交一次 offset 的更新,設當前 offset = 10,當消費者消費了 0.5s 的數據,offset 移動了 15,由於提交間隔爲 1s,因此這一 offset 的更新並不會被提交,這時候我們寫的消費者掛掉,重啓後,消費者會去 ZooKeeper 上獲取讀取位置,獲取到的 offset 仍爲10,它就會重複消費. 解決辦法使用低級消費者

Kafka中是怎麼體現消息順序性的?

kafka每個partition中的消息在寫入時都是有序的,消費時,每個partition只能被每一個group中的一個消費者消費,保證了消費時也是有序的。

整個topic不保證有序。如果爲了保證topic整個有序,那麼將partition調整爲1.

 

KAFKA速度快的原因:

直接使用linux的cache高效緩存數據

順序寫磁盤 減少尋址

使用零拷貝 傳統的數據發送需要發送四次上下切換,採用sendfile系統調用後,數據直接在內核態轉換,系統上下文切換變成2次

 

數據傳輸的事物定義有哪三種?

數據傳輸的事務定義通常有以下三種級別:

(1)最多一次: 消息不會被重複發送,最多被傳輸一次,但也有可能一次不傳輸

(2)最少一次: 消息不會被漏發送,最少被傳輸一次,但也有可能被重複傳輸.

(3)精確的一次(Exactly once): 不會漏傳輸也不會重複傳輸,每個消息都傳輸被一次而

且僅僅被傳輸一次,這是大家所期望的

 

Kafka 判斷一個節點是否還活着有那兩個條件?

(1)節點必須可以維護和 ZooKeeper 的連接,Zookeeper 通過心跳機制檢查每個節點的連

(2)如果節點是個 follower,他必須能及時的同步 leader 的寫操作,延時不能太久

producer 是否直接將數據發送到 broker 的 leader(主節點)?

producer 直接將數據發送到 broker 的 leader(主節點),不需要在多個節點進行分發,爲了

幫助 producer 做到這點,所有的 Kafka 節點都可以及時的告知:哪些節點是活動的,目標

topic 目標分區的 leader 在哪。這樣 producer 就可以直接將消息發送到目的地了

Kafa consumer 是否可以消費指定分區消息?

Kafa consumer 消費消息時,向 broker 發出"fetch"請求去消費特定分區的消息,consumer

指定消息在日誌中的偏移量(offset),就可以消費從這個位置開始的消息,customer 擁有

了 offset 的控制權,可以向後回滾去重新消費之前的消息,這是很有意義的

Kafka 消息是採用 Pull 模式,還是 Push 模式?

producer 將消息推送到 broker,consumer 從 broker 拉取消息

Kafka 存儲在硬盤上的消息格式是什麼?

消息由一個固定長度的頭部和可變長度的字節數組組成。頭部包含了一個版本號和 CRC32

校驗碼。

消息長度: 4 bytes (value: 1+4+n)

版本號: 1 byte

CRC 校驗碼: 4 bytes

具體的消息: n bytes

Kafka 與傳統消息系統之間有三個關鍵區別

(1).Kafka 持久化日誌,這些日誌可以被重複讀取和無限期保留

(2).Kafka 是一個分佈式系統:它以集羣的方式運行,可以靈活伸縮,在內部通過複製數據

提升容錯能力和高可用性

(3).Kafka 支持實時的流式處理

Kafka 高效文件存儲設計特點:

(1).Kafka 把 topic 中一個 parition 大文件分成多個小文件段,通過多個小文件段,就容易定

期清除或刪除已經消費完文件,減少磁盤佔用。

(2).通過索引信息可以快速定位 message 和確定 response 的最大大小。

(3).通過 index 元數據全部映射到 memory,可以避免 segment file 的 IO 磁盤操作。

(4).通過索引文件稀疏存儲,可以大幅降低 index 文件元數據佔用空間大小

Kafka 新建的分區會在哪個目錄下創建

在啓動 Kafka 集羣之前,我們需要配置好 log.dirs 參數,其值是 Kafka 數據的存放目錄,

這個參數可以配置多個目錄,目錄之間使用逗號分隔,通常這些目錄是分佈在不同的磁盤

上用於提高讀寫性能。

當然我們也可以配置 log.dir 參數,含義一樣。只需要設置其中一個即可。

如果 log.dirs 參數只配置了一個目錄,那麼分配到各個 Broker 上的分區肯定只能在這個

目錄下創建文件夾用於存放數據。

但是如果 log.dirs 參數配置了多個目錄,那麼 Kafka 會在哪個文件夾中創建分區目錄呢?

答案是:Kafka 會在含有分區目錄最少的文件夾中創建新的分區目錄,分區目錄名爲 Topic

名+分區 ID。注意,是分區文件夾總數最少的目錄,而不是磁盤使用量最少的目錄!也就

是說,如果你給 log.dirs 參數新增了一個新的磁盤,新的分區目錄肯定是先在這個新的磁

盤上創建直到這個新的磁盤目錄擁有的分區目錄不是最少爲止。

partition 的數據如何保存到硬盤

topic 中的多個 partition 以文件夾的形式保存到 broker,每個分區序號從 0 遞增,

且消息有序

Partition 文件下有多個 segment(xxx.index,xxx.log)

segment 文件裏的 大小和配置文件大小一致可以根據要求修改 默認爲 1g

如果大小大於 1g 時,會滾動一個新的 segment 並且以上一個 segment 最後一條消息的偏移

量命名

消費者負載均衡策略

一個消費者組中的一個分片對應一個消費者成員,他能保證每個消費者成員都能訪問,如

果組中成員太多會有空閒的成員

kafaka 生產數據時數據的分組策略

生產者決定數據產生到集羣的哪個 partition 中

每一條消息都是以(key,value)格式

Key 是由生產者發送數據傳入

所以生產者(key)決定了數據產生到集羣的哪個 partition

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