持續(xù)輸出面試題之Kafka篇

開篇介紹

大家好,我是Java最全面試題庫的提褲姐,今天這篇是中間件面試題系列的第三篇,主要總結了Kafka相關的面試題;在后續(xù),會沿著第一篇開篇的知識線路一直總結下去,做到日更!如果我能做到百日百更,希望你也可以跟著百日百刷,一百天養(yǎng)成一個好習慣。

Kafka中的ISR、AR代表什么?ISR的伸縮指什么?

  • ISR:In-Sync Replicas 副本同步隊列
  • AR:Assigned Replicas 所有副本

ISR是由leader維護,follower從leader同步數(shù)據(jù)有一些延遲(包括延遲時間replica.lag.time.max.ms延遲條數(shù)replica.lag.max.messages兩個維度,當前最新的版本0.10.x中只支持replica.lag.time.max.ms這個維度),任意一個超過閾值都會把follower剔除出ISR,存入OSR(Outof-Sync Replicas)列表,新加入的follower也會先存放在OSR中。

AR=ISR+OSR。

kafka中的broker 是干什么的?

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

kafka中的 zookeeper 起到什么作用?

zookeeper 是一個分布式的協(xié)調組件,早期版本的kafka用zk做meta信息存儲consumer的消費狀態(tài),group的管理以及 offset的值。
考慮到zk本身的一些因素以及整個架構較大概率存在單點問題,新版本中逐漸弱化了zookeeper的作用。新的consumer使用了kafka內部的group coordination協(xié)議,也減少了對zookeeper的依賴。

kafka follower如何與leader同步數(shù)據(jù)?

Kafka的復制機制既不是完全的同步復制,也不是單純的異步復制。
完全同步復制要求All Alive Follower都復制完,這條消息才會被認為commit,這種復制方式極大的影響了吞吐率。
異步復制方式下,F(xiàn)ollower異步的從Leader復制數(shù)據(jù),數(shù)據(jù)只要被Leader寫入log就被認為已經(jīng)commit,這種情況下,如果leader掛掉,會丟失數(shù)據(jù);
kafka使用ISR的方式很好的均衡了確保數(shù)據(jù)不丟失以及吞吐率。Follower可以批量的從Leader復制數(shù)據(jù),而且Leader充分利用磁盤順序讀以及send file(zero copy)機制,這樣極大的提高復制性能,內部批量寫磁盤,大幅減少了Follower與Leader的消息量差。

kafka 為什么那么快?

  • Cache Filesystem Cache PageCache緩存
  • 順序寫:由于現(xiàn)代的操作系統(tǒng)提供了預讀和寫技術,磁盤的順序寫大多數(shù)情況下比隨機寫內存還要快。
  • Zero-copy:零拷技術減少拷貝次數(shù)
  • Batching of Messages:批量量處理。合并小的請求,然后以流的方式進行交互,直頂網(wǎng)絡上限。
  • Pull 拉模式:使用拉模式進行消息的獲取消費,與消費端處理能力相符。

kafka producer如何優(yōu)化打入速度?

  • 增加線程
  • 提高 batch.size
  • 增加更多 producer 實例
  • 增加 partition 數(shù)
  • 設置 acks=-1 時,如果延遲增大:可以增大 num.replica.fetchers(follower 同步數(shù)據(jù)的線程數(shù))來調解;
  • 跨數(shù)據(jù)中心的傳輸:增加 socket 緩沖區(qū)設置以及 OS tcp 緩沖區(qū)設置。

kafka producer發(fā)送數(shù)據(jù),ack為0,1,-1分別是什么意思?

  • 1(默認) 數(shù)據(jù)發(fā)送到Kafka后,經(jīng)過leader成功接收消息的的確認,就算是發(fā)送成功了。在這種情況下,如果leader宕機了,則會丟失數(shù)據(jù)。
  • 0 生產(chǎn)者將數(shù)據(jù)發(fā)送出去就不管了,不去等待任何返回。這種情況下數(shù)據(jù)傳輸效率最高,但是數(shù)據(jù)可靠性確是最低的。
  • -1producer需要等待ISR中的所有follower都確認接收到數(shù)據(jù)后才算一次發(fā)送完成,可靠性最高。當ISR中所有Replica都向Leader發(fā)送ACK時,leader才commit,這時候producer才能認為一個請求中的消息都commit了。

kafka的message格式是什么樣的?

一個Kafka的Message由一個固定長度的header和一個變長的消息體body組成

  • header部分由一個字節(jié)的magic(文件格式)和四個字節(jié)的CRC32(用于判斷body消息體是否正常)構成。
    當magic的值為1的時候,會在magic和crc32之間多一個字節(jié)的數(shù)據(jù):attributes(保存一些相關屬性,
    比如是否壓縮、壓縮格式等等);如果magic的值為0,那么不存在attributes屬性

  • body是由N個字節(jié)構成的一個消息體,包含了具體的key/value消息

kafka中consumer group 是什么概念?

同樣是邏輯上的概念,是Kafka實現(xiàn)單播和廣播兩種消息模型的手段。
同一個topic的數(shù)據(jù),會廣播給不同的group;
同一個group中的worker,只有一個worker能拿到這個數(shù)據(jù)。
換句話說,對于同一個topic,每個group都可以拿到同樣的所有數(shù)據(jù),但是數(shù)據(jù)進入group后只能被其中的一個worker消費。group內的worker可以使用多線程或多進程來實現(xiàn),也可以將進程分散在多臺機器上,worker的數(shù)量通常不超過partition的數(shù)量,且二者最好保持整數(shù)倍關系,因為Kafka在設計時假定了一個partition只能被一個worker消費(同一group內)。

Kafka中的消息是否會丟失和重復消費?

消息發(fā)送
Kafka消息發(fā)送有兩種方式:同步(sync)和異步(async),
默認是同步方式,可通過producer.type屬性進行配置。
Kafka通過配置request.required.acks屬性來確認消息的生產(chǎn)

  • 0---表示不進行消息接收是否成功的確認;
  • 1---表示當Leader接收成功時確認;
  • -1---表示Leader和Follower都接收成功時確認;

綜上所述,有6種消息生產(chǎn)的情況,消息丟失的場景:

  • acks=0,不和Kafka集群進行消息接收確認,則當網(wǎng)絡異常、緩沖區(qū)滿了等情況時,消息可能丟失;
  • acks=1、同步模式下,只有Leader確認接收成功后但掛掉了,副本沒有同步,數(shù)據(jù)可能丟失;

消息消費
Kafka消息消費有兩個consumer接口,Low-level APIHigh-level API

  • Low-level API:消費者自己維護offset等值,可以實現(xiàn)對Kafka的完全控制;
  • High-level API:封裝了對parition和offset的管理,使用簡單;

如果使用高級接口High-level API,可能存在一個問題就是當消息消費者從集群中把消息取出來、并提交了新的消息offset值后,還沒來得及消費就掛掉了,那么下次再消費時之前沒消費成功的消息就“詭異”的消失了;

解決辦法:
針對消息丟失:同步模式下,確認機制設置為-1,即讓消息寫入Leader和Follower之后再確認消息發(fā)送成功;異步模式下,為防止緩沖區(qū)滿,可以在配置文件設置不限制阻塞超時時間,當緩沖區(qū)滿時讓生產(chǎn)者一直處于阻塞狀態(tài);

針對消息重復:將消息的唯一標識保存到外部介質中,每次消費時判斷是否處理過即可。

為什么Kafka不支持讀寫分離?

在 Kafka 中,生產(chǎn)者寫入消息、消費者讀取消息的操作都是與 leader 副本進行交互的,從 而實現(xiàn)的是一種主寫主讀的生產(chǎn)消費模型。

Kafka 并不支持主寫從讀,因為主寫從讀有 2 個很明 顯的缺點:

  • 數(shù)據(jù)一致性問題。數(shù)據(jù)從主節(jié)點轉到從節(jié)點必然會有一個延時的時間窗口,這個時間 窗口會導致主從節(jié)點之間的數(shù)據(jù)不一致。某一時刻,在主節(jié)點和從節(jié)點中 A 數(shù)據(jù)的值都為 X, 之后將主節(jié)點中 A 的值修改為 Y,那么在這個變更通知到從節(jié)點之前,應用讀取從節(jié)點中的 A 數(shù)據(jù)的值并不為最新的 Y,由此便產(chǎn)生了數(shù)據(jù)不一致的問題。
  • 延時問題。類似 Redis 這種組件,數(shù)據(jù)從寫入主節(jié)點到同步至從節(jié)點中的過程需要經(jīng)歷網(wǎng)絡→主節(jié)點內存→網(wǎng)絡→從節(jié)點內存這幾個階段,整個過程會耗費一定的時間。而在 Kafka 中,主從同步會比 Redis 更加耗時,它需要經(jīng)歷網(wǎng)絡→主節(jié)點內存→主節(jié)點磁盤→網(wǎng)絡→從節(jié)點內存→從節(jié)點磁盤這幾個階段。對延時敏感的應用而言,主寫從讀的功能并不太適用。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內容