你們好,我是Java最全面試題庫
的提褲姐,今天這篇是中間件面試題系列的第三篇,主要總結了Kafka相關的面試題;在後續,會沿着第一篇開篇的知識線路一直總結下去,作到日更!若是我能作到百日百更,但願你也能夠跟着百日百刷,一百天養成一個好習慣。面試
ISR
:In-Sync Replicas 副本同步隊列AR
:Assigned Replicas 全部副本ISR是由leader維護,follower從leader同步數據有一些延遲(包括延遲時間replica.lag.time.max.ms
和延遲條數replica.lag.max.messages
兩個維度,當前最新的版本0.10.x中只支持replica.lag.time.max.ms
這個維度),任意一個超過閾值都會把follower剔除出ISR,存入OSR(Outof-Sync Replicas)列表,新加入的follower也會先存放在OSR中。緩存
AR=ISR+OSR。
broker 是消息的代理,
Producers往Brokers裏面的指定Topic中寫消息,Consumers從Brokers裏面拉取指定Topic的消息,而後進行業務處理,broker在中間起到一個代理保存消息的中轉站。網絡
zookeeper 是一個分佈式的協調組件,早期版本的kafka用zk作meta信息存儲
,consumer的消費狀態
,group的管理
以及 offset
的值。
考慮到zk自己的一些因素以及整個架構較大機率存在單點問題,新版本中逐漸弱化了zookeeper的做用。新的consumer使用了kafka內部的group coordination
協議,也減小了對zookeeper的依賴。多線程
Kafka的複製機制既不是徹底的同步複製,也不是單純的異步複製。
徹底同步複製要求All Alive Follower
都複製完,這條消息纔會被認爲commit,這種複製方式極大的影響了吞吐率。
異步複製方式下,Follower異步的從Leader複製數據,數據只要被Leader寫入log就被認爲已經commit,這種狀況下,若是leader掛掉,會丟失數據;
kafka使用ISR
的方式很好的均衡了確保數據不丟失以及吞吐率。Follower能夠批量的從Leader複製數據,並且Leader充分利用磁盤順序讀以及send file(zero copy)
機制,這樣極大的提升複製性能,內部批量寫磁盤,大幅減小了Follower與Leader的消息量差。架構
順序寫
:因爲現代的操做系統提供了預讀和寫技術,磁盤的順序寫大多數狀況下比隨機寫內存還要快。Zero-copy
:零拷技術減小拷貝次數Batching of Messages
:批量量處理。合併小的請求,而後以流的方式進行交互,直頂網絡上限。Pull 拉模式
:使用拉模式進行消息的獲取消費,與消費端處理能力相符。batch.size
producer
實例partition
數acks=-1
時,若是延遲增大:能夠增大 num.replica.fetchers
(follower 同步數據的線程數)來調解;socket
緩衝區設置以及 OS tcp
緩衝區設置。1
(默認) 數據發送到Kafka後,通過leader成功接收消息的的確認,就算是發送成功了。在這種狀況下,若是leader宕機了,則會丟失數據。0
生產者將數據發送出去就無論了,不去等待任何返回。這種狀況下數據傳輸效率最高,可是數據可靠性確是最低的。-1
producer須要等待ISR中的全部follower都確認接收到數據後纔算一次發送完成,可靠性最高。當ISR中全部Replica都向Leader發送ACK時,leader才commit,這時候producer才能認爲一個請求中的消息都commit了。一個Kafka的Message由一個固定長度的header
和一個變長的消息體body
組成異步
magic
(文件格式)和四個字節的CRC32
(用於判斷body消息體是否正常)構成。當magic的值爲1的時候,會在magic和crc32之間多一個字節的數據:attributes
(保存一些相關屬性,
好比是否壓縮、壓縮格式等等);若是magic的值爲0,那麼不存在attributes屬性socket
key/value
消息一樣是邏輯上的概念,是Kafka實現單播和廣播兩種消息模型的手段。
同一個topic的數據,會廣播給不一樣的group;
同一個group中的worker,只有一個worker能拿到這個數據。
換句話說,對於同一個topic,每一個group均可以拿到一樣的全部數據,可是數據進入group後只能被其中的一個worker消費。group內的worker可使用多線程或多進程來實現,也能夠將進程分散在多臺機器上,worker的數量一般不超過partition的數量,且兩者最好保持整數倍關係,由於Kafka在設計時假定了一個partition只能被一個worker消費(同一group內)。async
消息發送
Kafka消息發送有兩種方式:同步(sync)和異步(async),
默認是同步方式,可經過producer.type
屬性進行配置。
Kafka經過配置request.required.acks
屬性來確認消息的生產tcp
綜上所述,有6種消息生產的狀況,消息丟失的場景:分佈式
消息消費
Kafka消息消費有兩個consumer接口,Low-level API
和High-level API
:
若是使用高級接口High-level API,可能存在一個問題就是當消息消費者從集羣中把消息取出來、並提交了新的消息offset值後,還沒來得及消費就掛掉了,那麼下次再消費時以前沒消費成功的消息就「詭異」的消失了;
解決辦法:
針對消息丟失:同步模式下,確認機制設置爲-1,即讓消息寫入Leader和Follower以後再確認消息發送成功;異步模式下,爲防止緩衝區滿,能夠在配置文件設置不限制阻塞超時時間,當緩衝區滿時讓生產者一直處於阻塞狀態;
針對消息重複:將消息的惟一標識保存到外部介質中,每次消費時判斷是否處理過便可。
在 Kafka 中,生產者寫入消息、消費者讀取消息的操做都是與 leader 副本進行交互的,從 而實現的是一種主寫主讀的生產消費模型。
Kafka 並不支持主寫從讀,由於主寫從讀有 2 個很明 顯的缺點:
網絡→主節點內存→網絡→從節點內存
這幾個階段,整個過程會耗費必定的時間。而在 Kafka 中,主從同步會比 Redis 更加耗時,它須要經歷網絡→主節點內存→主節點磁盤→網絡→從節點內存→從節點磁盤
這幾個階段。對延時敏感的應用而言,主寫從讀的功能並不太適用。