1、kafka在高並發的情況下,如何避免消息丟失和消息重復?
消息丟失解決方案:
首先對kafka進行限速, 其次啟用重試機制,重試間隔時間設置長一些,最后Kafka設置acks=all,即需要相應的所有處於ISR的分區都確認收到該消息后,才算發送成功
消息重復解決方案:
消息可以使用唯一id標識
生產者(ack=all 代表至少成功發送一次)
消費者 (offset手動提交,業務邏輯成功處理后,提交offset)
落表(主鍵或者唯一索引的方式,避免重復數據)
業務邏輯處理(選擇唯一主鍵存儲到Redis或者mongdb中,先查詢是否存在,若存在則不處理;若不存在,先插入Redis或Mongdb,再進行業務邏輯處理)
2、kafka怎么保證數據消費一次且僅消費一次
冪等producer:保證發送單個分區的消息只會發送一次,不會出現重復消息
事務(transaction):保證原子性地寫入到多個分區,即寫入到多個分區的消息要么全部成功,要么全部回滾流處理EOS:流處理本質上可看成是“讀取-處理-寫入”的管道。此EOS保證整個過程的操作是原子性。注意,這只適用於Kafka Streams
3、kafka保證數據一致性和可靠性
數據一致性保證
一致性定義:若某條消息對client可見,那么即使Leader掛了,在新Leader上數據依然可以被讀到
HW-HighWaterMark: client可以從Leader讀到的最大msg offset,即對外可見的最大offset, HW=max(replica.offset)
對於Leader新收到的msg,client不能立刻消費,Leader會等待該消息被所有ISR中的replica同步后,更新HW,此時該消息才能被client消費,這樣就保證了如果Leader fail,該消息仍然可以從新選舉的Leader中獲取。
對於來自內部Broker的讀取請求,沒有HW的限制。同時,Follower也會維護一份自己的HW,Folloer.HW = min(Leader.HW, Follower.offset)
數據可靠性保證
當Producer向Leader發送數據時,可以通過acks參數設置數據可靠性的級別
0: 不論寫入是否成功,server不需要給Producer發送Response,如果發生異常,server會終止連接,觸發Producer更新meta數據;
1: Leader寫入成功后即發送Response,此種情況如果Leader fail,會丟失數據
-1: 等待所有ISR接收到消息后再給Producer發送Response,這是最強保證
4、kafka到spark streaming怎么保證數據完整性,怎么保證數據不重復消費?
保證數據不丟失(at-least)
spark RDD內部機制可以保證數據at-least語義。
Receiver方式
開啟WAL(預寫日志),將從kafka中接受到的數據寫入到日志文件中,所有數據從失敗中可恢復。
Direct方式
依靠checkpoint機制來保證。
保證數據不重復(exactly-once)
要保證數據不重復,即Exactly once語義。
- 冪等操作:重復執行不會產生問題,不需要做額外的工作即可保證數據不重復。
- 業務代碼添加事務操作
就是說針對每個partition的數據,產生一個uniqueId,只有這個partition的所有數據被完全消費,則算成功,否則算失效,要回滾。下次重復執行這個uniqueId時,如果已經被執行成功,則skip掉。