由於在具體開發中某些環節考慮使用kafka卻擔憂有消息丟失的風險,本週結合項目對kafka的消息可靠性作了一下調研和總結:網絡
首先明確一下丟消息的定義。kafka集羣中的部分或所有broker掛了,致使consumer沒有及時收到消息,這不屬於丟消息。broker掛了,只要消息所有持久化到了硬盤上,重啓broker集羣以後,使消費者繼續拉取消息,消息就沒有丟失,仍然全量消費了。運維
以個人理解,所謂丟消息,意味着:開發人員未感知到哪些消息沒有被消費。性能
我把消息的丟失概括瞭如下幾種狀況:.net
1)、 producer把消息發送給broker,由於網絡抖動,消息沒有到達broker,且開發人員無感知。blog
解決方案:producer設置acks參數,消息同步到master以後返回ack信號,不然拋異常使應用程序感知到並在業務中進行重試發送。這種方式必定程度保證了消息的可靠性,producer等待broker確認信號的時延也不高。內存
2)、 producer把消息發送給broker-master,master接收到消息,在未將消息同步給follower以前,掛掉了,且開發人員無感知。開發
解決方案:producer設置acks參數,消息同步到master且同步到全部follower以後返回ack信號,不然拋異常使應用程序感知到並在業務中進行重試發送。這樣設置,在更大程度上保證了消息的可靠性,缺點是producer等待broker確認信號的時延比較高。kafka
3)、 producer把消息發送給broker-master,master接收到消息,master未成功將消息同步給每一個follower,有消息丟失風險。同步
解決方案:同上。ast
4)、 某個broker消息還沒有從內存緩衝區持久化到磁盤,就掛掉了,這種狀況沒法經過ack機制感知。
解決方案:設置參數,加快消息持久化的頻率,能在必定程度上減小這種狀況發生的機率。但提升頻率天然也會影響性能。
5)、consumer成功拉取到了消息,consumer掛了。
解決方案:設置手動sync,消費成功才提交。
綜上所述,集羣/項目運轉正常的狀況下,kafka不會丟消息。一旦集羣出現問題,消息的可靠性沒法徹底保證。要想盡量保證消息可靠,基本只能在發現消息有可能沒有被消費時,重發消息來解決。因此在業務邏輯中,要考慮消息的重複消費問題,對於關鍵環節,要有冪等機制。
幾條建議:
1)、若是一個業務很關鍵,使用kafka的時候要考慮丟消息的成本和解決方案。
2)、producer端確認消息是否到達集羣,如有異常,進行重發。
3)、consumer端保障消費冪等性。
4)、運維保障集羣運轉正常且高可用,保障網絡情況良好。————————————————版權聲明:本文爲CSDN博主「qrne06」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處連接及本聲明。原文連接:https://blog.csdn.net/qrne06/article/details/94225070