kafka中有三種語義:
1、at-most-once
配置應答模式ack為0時,只要消息到了broker無論是否寫成功,就回復ok,這樣可能導致消息沒有寫入kafka;這種做法一般是為了減少消息的重復性,而且業務必須接受數據的丟失
2、at-least-once
producer在收到ack時,證明消息已經寫入kafka;但是ack超時或者返回錯誤,producer會嘗試重新發送消息;
試想,如果消息已經寫入kafka,但是在回復ack時異常,此時會導致消息被寫入kafka兩次,消費者在處理消息時要做去重處理
3、at-exactly-once
0.11版本的kafka引入了冪等性 --- 無論producer向kafka發送多少相同的消息,kafka知會持久化一條;
也就是說at-least-once + 冪等性 = at-exactly-once
冪等性的原理是什么?
啟用冪等性:創建生產者時,設置enable.idompotence參數為true;
啟用冪等性的生產者在創建的時候會自動分配一個PID,並且發送給同一個分區的消息會攜帶序列號SeqNum;
broker端緩存<PID, PartitionKey, SeqNum>,當有相同key的消息時,broker只會持久化一條
需要注意的是,
1、冪等性無法跨分區實現at-exactly-once;這是因為PID在生產者重啟后會改變,並且不同分區的PartitionKey也不一致
2、啟用冪等性后,acks參數的取值一定是all或者-1
這些問題也可以解決,后面會說到:生產者事務