一、消息傳遞語義:三種,至少一次,至多一次,精確一次
1、at lest once:消息不丟,但可能重復
2、at most once:消息會丟,但不會重復
3、Exactly Once:消息不丟,也不重復。
二、數據一致性保證:保證消息不丟、消息不重復
消息不丟:副本機制+ack,可以保證消息不丟。
數據重復:brocker保存了消息之后,在發送ack之前宕機了,producer認為消息沒有發送成功進行重試,導致數據重復。
數據亂序:前一條消息發送失敗,后一條消息發送成功,前一條又重試,成功了,導致數據亂序。
三、消息一致性保證:主要就是保證Exactly Once,即:數據不丟、數據不重復
1、0.11之前的kafka版本:保證消息丟,要在消息發送端和消費端都要進行保證。保證消息不重復,就是要對消息冪等,即去重
(1)消息發送端
request.required.acks 設置數據可靠性級別:
request.required.acks=1:當且僅當leader收到消息后返回commit確認信號后,消息發送成功。但有弊端,leader宕機,也就是還沒有將消息同步到follower,這是會發生消息丟失。
request.required.acks=0:消息發送了,即認為成功,可靠性最低。
request.required.acks=-1:發送端等待isr列表所有的成員確認消息,才算成功,可靠性最高延遲最大。
(2)消息消費端
消費者關閉自動提交,enable.auto.commit:false,消費者收到消息處理完業務邏輯后,再手動提交commitSync offersets。這樣可以保證消費者即使在消息處理過程中掛掉,下次重啟,也可以從之前的offersets進行消費,消息不丟。
(3)消息去重:主要借助於業務系統本身的業務處理或大數據組件冪等。如:hbase 、elasticsearch冪等。
Hbse冪等:將消息從kafka消費出來,保存到hbase中,使用id主鍵+時間戳,只有插入成功后才往 kafka 中持久化 offset。這樣的好處是,如果在中間任意一個階段發生報錯,程序恢復后都會從上一次持久化 offset 的位置開始消費數據,而不會造成數據丟失。如果中途有重復消費的數據,則插入 hbase 的 rowkey 是相同的,數據只會覆蓋不會重復,最終達到數據一致。