kafka高階知識點面試題

2021-10-06 16:46:53 字數 3261 閱讀 9214

在老版本kafka中,訊息都是來一條傳送一條,這種方式會造成訊息傳送的吞吐量比較低,所以之後kafka對這種方式進行了優化,提供了批量傳送的方式,把多條訊息繫結成一批訊息傳送,以此來提高訊息傳送的吞吐率。

這種方式就是緩衝池的思想,傳送訊息的邏輯大概如下:

1、把訊息封裝成producerrecord物件

2、訊息序列化(可自定義)

3、訊息分割槽(可自定義)

4、訊息被放入緩衝池中

5、會有乙個sender執行緒,從緩衝池取資料,然後把多條訊息再封裝成有乙個批次,再一次傳送出去。

kafka傳送訊息時,會將多條訊息組成乙個batch再進行批量傳送,這樣做的目的是可以提高kafka的吞吐量,不必每次來一條訊息就進行一次網路請求,那麼這些批量的訊息傳送出去後,必然還存在於記憶體中,等待的將是jvm的gc,當訊息越來越多時,帶來的問題就是頻繁的gc,也就是會造成頻繁的stw。

針對上述問題,於是kafka就設計出了緩衝池的概念,kafka先將一片記憶體區域固定下來專門用於存放batch,每次從緩衝池申請batch,使用完後再還回緩衝池,這樣就避免了每次對於batch的申請與**,解決了jvm 頻繁gc的問題。

當緩衝池滿了以後,也就是說訊息寫入的速度大於向broker傳送的速度,那麼就阻塞寫入,直到緩衝池中有空餘記憶體時為止。

一般topic下都會建立多個分割槽,這樣可以提高消費者的效率,kafka在建立之初就會對應好每個分割槽對應的消費者,例如現在有3個分割槽與3個消費者,那麼kafka一般會按照乙個分割槽對應乙個消費者的方式,1分割槽的訊息全部傳送到1消費者,以此類推,所以當消費者數量大於分割槽數量時,多餘的消費者將不會得到訊息,資源浪費,當消費者數量小於分割槽數量時,那麼乙個消費者就會對應多個分割槽。

當你在傳送時沒有指定key時,kafka將按照輪詢的方式依次將訊息傳送到每個分割槽,但如果你指定了key,那麼會根據key的hash值與分割槽取模,計算出應該傳送到哪個分割槽,所以當我們通過指定key的方式傳送,如果設定不合理那麼會造成kafka的分割槽不均勻,導致某些消費者壓力過高,某些消費者太過空閒。

kafka中每個分割槽都有乙個分割槽leader與0到多個分割槽追隨者,leader負責訊息的接收與傳送,追隨者不會處理訊息,追隨者會不停的從leader拉取訊息保持自己的leader的同步,通過這種冗餘設計,提高了kafka的可用性,當某個分割槽中的leader掛了,則會選舉乙個追隨者為新的leader。

由於只有分割槽leader才會處理訊息,所以一般kafka會均勻的將leader安排在不同的broker中,使得broker負載更均衡。

isr意為與分割槽leader保持同步的副本集合,當leader宕機時,kafka會優先從isr中選舉乙個追隨者作為新的leader,追隨者會不斷同步leader中的訊息,但是如果追隨者出現了卡頓(gc)、宕機、拉取訊息的速度跟不上leader接收到訊息的速度、或是其他原因導致與leader中的訊息差距太大,則會從isr中踢出。

在0.9.0.0版本之前,有乙個引數replica.lag.max.messages,意為當副本中的追隨者與leader最多相差多少條訊息時,則會被踢出,這個引數在突發流量的場景下很容易造成追隨者被頻繁的踢出,平穩後又被加入isr中。

所以現在衡量乙個追隨者是否能存在isr中只有乙個引數replica.lag.time.max.ms,意為最長多少時間不向leader請求資料,則被判定不同步,被踢出isr。

假如isr列表中只有leader自己,其他所有的副本都沒有與leader保持同步,那麼這時候如果leader宕機了,該怎麼辦呢?

第一種方案可能會造成等待時間較長,如果isr中所有的副本都無法活過來了,則分割槽會變的永久不可用。

第二種方案雖然可能會丟失訊息,但是保證了高可用

unclean.leader.election.enable引數決定使用哪一種,預設true,即允許不完全選舉。

min.insync.replicas:最小同步副本,生產者是需要等所有的isr中的副本都接收到訊息後才會commit,所以如果要確保已提交的訊息被寫入多個副本,則此引數必須設定大於1,生產者會等待直到所有isr副本收到訊息,等待過程中如果傳送資料生產者會收到notenoughreplica***ception異常,注意此引數必須配置ack=all時,才會生效,很明顯非all時,其他邏輯與此配置衝突。

kafka利用作業系統快取的機制,在資料寫入時並不是直接寫入磁碟,而是先寫入作業系統記憶體中,這就相當於記憶體寫入了,再根據作業系統自己決定什麼時候將記憶體中的資料刷入磁碟中,這就大大提高了寫入磁碟的速度。

kafka利用磁碟順序寫的方式,訊息都是被追加到檔案尾部,磁碟順序寫的速度也是可以媲美記憶體的。

所以總結下,kafka利用作業系統快取的特性,以記憶體寫的方式將訊息寫入作業系統快取中,再通過磁碟順序寫的方式,進行刷盤,以此來提高磁碟寫入的速度。

當消費者從broker中拉取訊息時,實際上kafka需要將訊息從磁碟讀取然後再給消費者,我們都知道傳統的這乙個過程需要經歷4次資料copy和4次作業系統上下文切換,但是kafka利用了零拷貝技術,避免了磁碟資料複製到應用程式的過程,kafka中的模型為,先看os cache中是否有資料,如果有直接從os cache拷貝到網絡卡裝置(如果有dma的支援,可只將描述符拷貝到socket緩衝區。作業系統緩衝區的記憶體位址和記憶體偏移量),否則從磁碟拷貝到os cache再拷貝到網絡卡裝置,可以看出如果生產者和消費者引數配置的合理,訊息可以全部通過os cache獲取,經歷一次copy即可完成資料的傳輸,相當於在記憶體中完成了資料的讀寫。

kafka每個topic一般會有多個分割槽,每個分割槽會按照一定規則(輪詢等,也可以自定義)分配給對應的消費者,那麼一旦消費者無法接收訊息後,那麼必須對分割槽進行重新分配,保證訊息能夠正常的被消費。

kafka監控消費者是否在消費的方式主要是通過消費者傳送心跳包來實現的,消費者傳送心跳包的途徑主要有兩種,一種是輪詢poll,一種是提交offset,所以只要在正常的時間間隔內向broker傳送心跳,就被認為是存活的,max.poll.interval.ms引數規定了間隔的時間,如果設定太小,可能會頻繁的觸發分割槽再平衡,預設為30s。

max.poll.records引數設定了每次poll的訊息數量,如果數量過多,可能會導致後續處理訊息時間無法在指定間隔時間內完成,觸發再平衡。

akc有三個引數:0、1、all(-1)

0:生產者只要把訊息傳送出去即可,不用等待broker的處理結果,吞吐量最高,同樣訊息的丟失率也最高。

1:生成者需要等分割槽leader將訊息寫入成功後 才認為此訊息傳送成功,1是ack的預設配置,兼顧了吞吐量和訊息丟失的問題,但是同樣有訊息丟失的風險,比如當leader寫入成功後突然掛了,其他分割槽跟隨者並為能夠將此訊息同步,則此訊息丟失。

all:生產者會等待所有的副本都寫入成功後才認為此訊息傳送成功,此方法保證了訊息不丟失,但也是吞吐量最低的。

Kafka面試題 一些重要的核心知識點

broker broker是kafka的例項,每台伺服器都有乙個或多個broker,borker端不維護資料的消費狀態,直接用磁碟儲存資料,線性讀寫,提高效率。producer 發布者,將訊息推送給broker consumer 消費者,從broker端拉取訊息 topic 傳送到broker的訊息...

大資料面試題知識點分析(五)

a 一種可以加快批量寫入速度的方法是通過預先建立一些空的regions,這樣當資料寫入hbase時,會按照region分割槽情況,在集群內做資料的負載均衡。b hbase 裡面有這樣乙個hfileoutputformat類,他的實現可以將資料轉換成hfile格式,通過new乙個這個類,進行相關配置,...

大資料面試題知識點分析(六)

不支援,可以用left join 實現此功能。1.儲存於記憶體資料庫derby,此方法只能開啟乙個hive客戶端,不推薦使用。2.儲存於mysql資料庫,可以多客戶端連線,推薦使用。分為本地mysql資料庫,遠端mysql資料庫,但是本地的mysql資料用的比較多,因為本地讀寫速度都比較快。1.jo...