Kafka 如何保證訊息可靠性
訊息可靠性的保證基本上我們都要從3個方面來闡述(這樣才比較全面,無懈可擊)
1 生產者傳送訊息丟失
kafka支援3種方式傳送訊息,這也是常規的3種方式,傳送後不管結果、同步傳送、非同步傳送,基本上所有的訊息佇列都是這樣玩的。
傳送並忘記,直接呼叫傳送send方法,不管結果,雖然可以開啟自動重試,但是肯定會有訊息丟失的可能
同步傳送,同步傳送返回Future物件,我們可以知道傳送結果,然後進行處理
非同步傳送,傳送訊息,同時指定一個回撥函式,根據結果進行相應的處理
為了保險起見,一般我們都會使用非同步傳送帶有回撥的方式進行傳送訊息,再設定引數為傳送訊息失敗不停地重試。
acks=all,這個引數有可以配置0|1|all。
0表示生產者寫入訊息不管伺服器的響應,可能訊息還在網路緩衝區,伺服器根本沒有收到訊息,當然會丟失訊息。
1表示至少有一個副本收到訊息才認為成功,一個副本那肯定就是叢集的Leader副本了,但是如果剛好Leader副本所在的節點掛了,Follower沒有同步這條訊息,訊息仍然丟失了。
配置all的話表示所有ISR都寫入成功才算成功,那除非所有ISR裡的副本全掛了,訊息才會丟失。
retries=N,設定一個非常大的值,可以讓生產者傳送訊息失敗後不停重試
2 kafka broker 自身訊息丟失
kafka因為訊息寫入是通過PageCache非同步寫入磁碟的,因此仍然存在丟失訊息的可能。
因此針對kafka自身丟失的可能設定引數:
replication.factor=N,設定一個比較大的值,保證至少有2個或者以上的副本。
min.insync.replicas=N,代表訊息如何才能被認為是寫入成功,設定大於1的數,保證至少寫入1個或者以上的副本才算寫入訊息成功。
unclean.leader.election.enable=false,這個設定意味著沒有完全同步的分割槽副本不能成為Leader副本,如果是true的話,那些沒有完全同步Leader的副本成為Leader之後,就會有訊息丟失的風險。
3 消費者訊息丟失
消費者丟失的可能就比較簡單,關閉自動提交位移即可,改為業務處理成功手動提交。
因為重平衡發生的時候,消費者會去讀取上一次提交的偏移量,自動提交預設是每5秒一次,這會導致重複消費或者丟失訊息。
enable.auto.commit=false,設定為手動提交。
還有一個引數我們可能也需要考慮進去的:
auto.offset.reset=earliest,這個引數代表沒有偏移量可以提交或者broker上不存在偏移量的時候,消費者如何處理。earliest代表從分割槽的開始位置讀取,可能會重複讀取訊息,但是不會丟失,消費方一般我們肯定要自己保證冪等,另外一種latest表示從分割槽末尾讀取,那就會有概率丟失訊息。
綜合這幾個引數設定,我們就能保證訊息不會丟失,保證了可靠性。