更多精彩 第一時間直達(dá) 本文來源 | 石杉的架構(gòu)筆記 面試題如何保證消息的可靠性傳輸?或者說,如何處理消息丟失的問題? 面試官心理分析這個是肯定的,用 MQ 有個基本原則,就是數(shù)據(jù)不能多一條,也不能少一條,不能多,就是前面說的重復(fù)消費(fèi)和冪等性問題。不能少,就是說這數(shù)據(jù)別搞丟了。那這個問題你必須得考慮一下。 如果說你這個是用 MQ 來傳遞非常核心的消息,比如說計(jì)費(fèi)、扣費(fèi)的一些消息,那必須確保這個 MQ 傳遞過程中絕對不會把計(jì)費(fèi)消息給弄丟。 面試題剖析數(shù)據(jù)的丟失問題,可能出現(xiàn)在生產(chǎn)者、MQ、消費(fèi)者中,咱們從 RabbitMQ 和 Kafka 分別來分析一下吧。 RabbitMQ生產(chǎn)者弄丟了數(shù)據(jù)生產(chǎn)者將數(shù)據(jù)發(fā)送到 RabbitMQ 的時候,可能數(shù)據(jù)就在半路給搞丟了,因?yàn)榫W(wǎng)絡(luò)問題啥的,都有可能。 此時可以選擇用 RabbitMQ 提供的事務(wù)功能,就是生產(chǎn)者發(fā)送數(shù)據(jù)之前開啟 RabbitMQ 事務(wù) // 開啟事務(wù) 但是問題是,RabbitMQ 事務(wù)機(jī)制(同步)一搞,基本上吞吐量會下來,因?yàn)樘男阅?/span>。 所以一般來說,如果你要確保說寫 RabbitMQ 的消息別丟,可以開啟 事務(wù)機(jī)制和 所以一般在生產(chǎn)者這塊避免數(shù)據(jù)丟失,都是用 RabbitMQ 弄丟了數(shù)據(jù)就是 RabbitMQ 自己弄丟了數(shù)據(jù),這個你必須開啟 RabbitMQ 的持久化,就是消息寫入之后會持久化到磁盤,哪怕是 RabbitMQ 自己掛了,恢復(fù)之后會自動讀取之前存儲的數(shù)據(jù),一般數(shù)據(jù)不會丟。除非極其罕見的是,RabbitMQ 還沒持久化,自己就掛了,可能導(dǎo)致少量數(shù)據(jù)丟失,但是這個概率較小。 設(shè)置持久化有兩個步驟:
必須要同時設(shè)置這兩個持久化才行,RabbitMQ 哪怕是掛了,再次重啟,也會從磁盤上重啟恢復(fù) queue,恢復(fù)這個 queue 里的數(shù)據(jù)。 注意,哪怕是你給 RabbitMQ 開啟了持久化機(jī)制,也有一種可能,就是這個消息寫到了 RabbitMQ 中,但是還沒來得及持久化到磁盤上,結(jié)果不巧,此時 RabbitMQ 掛了,就會導(dǎo)致內(nèi)存里的一點(diǎn)點(diǎn)數(shù)據(jù)丟失。 所以,持久化可以跟生產(chǎn)者那邊的 消費(fèi)端弄丟了數(shù)據(jù)RabbitMQ 如果丟失了數(shù)據(jù),主要是因?yàn)槟阆M(fèi)的時候,剛消費(fèi)到,還沒處理,結(jié)果進(jìn)程掛了,比如重啟了,那么就尷尬了,RabbitMQ 認(rèn)為你都消費(fèi)了,這數(shù)據(jù)就丟了。 這個時候得用 RabbitMQ 提供的 Kafka消費(fèi)端弄丟了數(shù)據(jù)唯一可能導(dǎo)致消費(fèi)者弄丟數(shù)據(jù)的情況,就是說,你消費(fèi)到了這個消息,然后消費(fèi)者那邊自動提交了 offset,讓 Kafka 以為你已經(jīng)消費(fèi)好了這個消息,但其實(shí)你才剛準(zhǔn)備處理這個消息,你還沒處理,你自己就掛了,此時這條消息就丟咯。 這不是跟 RabbitMQ 差不多嗎,大家都知道 Kafka 會自動提交 offset,那么只要關(guān)閉自動提交 offset,在處理完之后自己手動提交 offset,就可以保證數(shù)據(jù)不會丟。但是此時確實(shí)還是可能會有重復(fù)消費(fèi),比如你剛處理完,還沒提交 offset,結(jié)果自己掛了,此時肯定會重復(fù)消費(fèi)一次,自己保證冪等性就好了。 生產(chǎn)環(huán)境碰到的一個問題,就是說我們的 Kafka 消費(fèi)者消費(fèi)到了數(shù)據(jù)之后是寫到一個內(nèi)存的 queue 里先緩沖一下,結(jié)果有的時候,你剛把消息寫入內(nèi)存 queue,然后消費(fèi)者會自動提交 offset。然后此時我們重啟了系統(tǒng),就會導(dǎo)致內(nèi)存 queue 里還沒來得及處理的數(shù)據(jù)就丟失了。 Kafka 弄丟了數(shù)據(jù)這塊比較常見的一個場景,就是 Kafka 某個 broker 宕機(jī),然后重新選舉 partition 的 leader。大家想想,要是此時其他的 follower 剛好還有些數(shù)據(jù)沒有同步,結(jié)果此時 leader 掛了,然后選舉某個 follower 成 leader 之后,不就少了一些數(shù)據(jù)?這就丟了一些數(shù)據(jù)啊。 生產(chǎn)環(huán)境也遇到過,我們也是,之前 Kafka 的 leader 機(jī)器宕機(jī)了,將 follower 切換為 leader 之后,就會發(fā)現(xiàn)說這個數(shù)據(jù)就丟了。 所以此時一般是要求起碼設(shè)置如下 4 個參數(shù):
我們生產(chǎn)環(huán)境就是按照上述要求配置的,這樣配置之后,至少在 Kafka broker 端就可以保證在 leader 所在 broker 發(fā)生故障,進(jìn)行 leader 切換時,數(shù)據(jù)不會丟失。 生產(chǎn)者會不會弄丟數(shù)據(jù)?如果按照上述的思路設(shè)置了 |
|