面試官:對于 MQ 中的消息丟失你是如何理解的?
相信很多的小伙伴在面試的時候,涉及到MQ的面試題,消息丟失是必問面試題之一。那么對于消息丟失你又是如何理解的呢?
下面我們一起來看一下。
本文以 Kafka 舉例說明。
一、什么是消息丟失?
消息丟失的定義是:在消息傳遞的過程中,在某個環(huán)節(jié)意外丟失,也就是消息沒有成功的發(fā)送或者沒有被正確的接收。
生產(chǎn)者未能成功發(fā)送消息。
消費者未能正確接收消息。
消費者未能正確處理消息。
對于第三條可以理解為特殊的消息丟失,因為消費者的邏輯處理錯誤,程序bug等其他原因,造成消息在處理過程中消息丟失或者被忽略(異常之后錯誤的應答等),也就是說消息沒有正確的被消費掉,我們也可以認為是一種消息丟失。
二、消息丟失的原因有哪些
1.消息生產(chǎn)階段
- 生產(chǎn)者配置錯誤:生產(chǎn)者在發(fā)送消息時,配置錯誤的主體、分區(qū)或者消息的過期時間,造成消息無法正確發(fā)送到MQ中。
- 網(wǎng)絡故障:生產(chǎn)者與MQ集群之間網(wǎng)絡故障。
2.消息存儲階段
- 磁盤故障:以Kafka舉例,如果磁盤出現(xiàn)故障,Kafka中的消息無法洛盤,可能導致消息的丟失。
- 日志壓縮策略:使用了壓縮比較高的壓縮策略從而可能在壓縮的過程中丟失消息。
3.消息消費階段
- 消費者處理失?。涸谔幚硐M邏輯時,由于程序bug等原因,造成系統(tǒng)異常,錯誤應答從而丟失消息。
- 消費者提交偏移量錯誤:當消費者消費完消息之后,提交錯誤的偏移量造成消息的重復消費或者消息丟失。
三、消息丟失的解決方案有哪些
1.消息生產(chǎn)階段
(1) 配置正確的主體、分區(qū)、以及TTL。
(2) 使用ACK應答,等待消息被MQ寫入成功之后在確認為發(fā)送成功。
- ack=1:默認值,leader副本成功寫入消息即發(fā)送成功。
- ack=0:發(fā)送消息后不等待服務端確認。
- ack=-1或者ack=all:生產(chǎn)者需要等待ISR中的所有副本都成功寫入消息才為消息發(fā)送成功。
(3) 消息發(fā)送重試。
- retries:配置生產(chǎn)者發(fā)送消息重試次數(shù)。
(4) 配置合理的壓縮策略。
- compression.type 支持none、gzip、snappy、lz4、zstd。
(5) 設置合理的消息緩沖區(qū)大小。
- buffer.memory:默認33554432。生產(chǎn)者用于緩存一批發(fā)送到服務器消息的總內(nèi)存字節(jié)數(shù)。
(6) 使用合適的序列化器,防止序列號錯誤造成消息丟失。
其他的配置可以參考官網(wǎng) Kafka 生產(chǎn)者配置:https://kafka.apache.org/documentation/#producerconfigs
2.消息存儲階段
- 配置適當?shù)母北緮?shù)量和ISR。在發(fā)生故障的時候消息仍然可以從其他的副本中進行恢復。
- 使用監(jiān)控,實時檢測消息的復制、磁盤的使用率。
- 定期備份。
3.消息消費階段
(1) 編寫健壯的代碼,說的容易,寫起來還是得多測試。對于可能產(chǎn)生的異常原因進行分析處理。當發(fā)生異常時,可以做如下處理:
- 記錄錯誤,有異常處理機制,保證能夠正確的處理異常情況。
- 消息重試消息。(需要注意消費冪等以及死循環(huán)造成消息堆積)
(2) 使用手動提交偏移量。(需保證所有的異常情況代碼中都有對應的異常處理機制,也就是第一點,健壯的代碼)
(3) 使用自動提交偏移量。(需要保證消費邏輯正確)
(4) 使用監(jiān)控,監(jiān)控消費者的消費情況,發(fā)現(xiàn)異常立即上報。
(5) 正確的消費者組管理,類似消費者重平衡或者重啟等造成的消息偏移量丟失。
(6) 備份,發(fā)生異?;蛘呦G失時,可以跟蹤到消費者的消費情況,直接使用備份恢復。
總結(jié)
上面我們分析了什么是消息丟失,產(chǎn)生的原因有哪些以及如何解決。通過看完這篇文章相信你對Kafka中的消息丟失也有了一定的了解,在工作中使用的時候也就不會沒有底氣了。
相信有眼尖的小伙伴發(fā)現(xiàn)了,在消費者的處理邏輯中,多次消費會造成消息的多次重復消費。消息的重試也有可能造成消息的堆積。那么這些問題就是下節(jié)課我們要說的。