Apache Kafka訊息傳遞精確正好一次的含義 | TechMyTalk
在分散式環境中,故障是很常見的情況,可以隨時發生。在Kafka環境中,訊息代理可能會崩潰,網路故障,處理故障,釋出訊息時失敗或無法使用訊息等。這些不同的情況導致了不同型別的資料丟失和重複。
失敗場景
- A(確認失敗): 生產者成功釋出了訊息,但由於失敗而未收到確認回執。在這種情況下,生產者將重試相同的訊息,可能會引入重複訊息。
- B(生產者程式在批處理訊息中失敗): 生產者傳送了一批失敗的訊息,但釋出成功的很少。在這種情況下,一旦生產者重新啟動,它將再次批次重新發布所有訊息,這將在Kafka中引入重複訊息。
- C( 觸發並忘記失敗)生產者釋出的訊息,重試= 0(觸發並忘記)。如果失敗,釋出的訊息將不知道並繼續傳送下一條訊息,這將導致上一條訊息丟失。
- D(批處理訊息中的消費者失敗) 消費者從Kafka接收到一批訊息,並手動提交其偏移量(enable.auto.commit = false)。如果消費者在提交給Kafka之前失敗,則下次消費者將再次使用相同的記錄,這些記錄將在消費者端複製副本。
精確一次語義
在這種情況下,即使生產者嘗試重新傳送訊息,它也導致訊息將被消費者釋出和消費一次。
為了在Kafka中實現Exactly-Once語義,它使用以下3個屬性:
- enable.idempotence = true
- MAX_IN_FLIGHT_REQUESTS_PER_CONNECTION = 5(生產者每次連線總是有一個飛行中請求)
- isolated.level = read_committed
啟用冪等(enable.idempotence = true)
冪等傳遞使生產者可以在單個生產者的生命週期內,將訊息僅一次寫入Kafka到主題的特定分割槽,而不會造成資料丟失和每個分割槽的訂單。
“請注意,啟用冪等性要求MAX_IN_FLIGHT_REQUESTS_PER_CONNECTION小於或等於5,RETRIES_CONFIG大於0且ACKS_CONFIG為'all'。如果使用者未明確設定這些值,則將選擇合適的值。如果設定了不相容的值,將丟擲ConfigException”
為了實現冪等性,Kafka在生成訊息時使用唯一的ID(稱為產品ID或PID和序列號)。生產者在釋出的每個訊息上保持遞增的序列號,這些訊息具有唯一的PID。代理總是將當前序列號與前一個序列號進行比較,如果新序列號不比上一個序列號大+1,則它會拒絕,這會避免重複;如果訊息中丟失了更多的序列號,則會拒絕同時顯示
在失敗的情況下,代理將序列號與先前的序列號進行比較,如果序列不增加,+ 1將拒絕該訊息。
事務(isolation.level)
事務使我們能夠自動更新多個主題分割槽中的資料。事務中包含的所有記錄都將被成功儲存,或者沒有儲存成功,它允許您將同一個事務中的消費者補償與已處理的資料一起提交,從而允許端到端的一次精確語義。
生產者不等待將訊息寫到kafka,生產者使用beginTransaction,commitTransaction和abortTransaction(如果發生故障),消費者使用isolate.level級別:要麼是read_committed要麼是read_uncommitted
- read_committed:使用者將始終僅讀取提交的資料。
- read_uncommitted:以偏移順序讀取所有訊息,而無需等待事務提交
如果具有Isolation.level = read_committed的使用者到達尚未完成的事務的控制訊息,它將不會再從該分割槽傳遞任何訊息,直到生產者提交或中止該事務或發生事務超時。事務超時由生產者使用配置transaction.timeout.ms(預設為1分鐘)確定。
生產者和消費者中的確切時間
在正常情況下,生產者和消費者是分開的。生產者必須具有冪等性並同時管理事務,以便消費者可以使用isolation.level讀取read_committed以使整個過程成為原子操作。這樣可以確保生產者將始終與源系統同步。即使生產者崩潰或事務中止,它也始終是一致的,並且一次將訊息或一批訊息釋出為一個單元。
同一使用者一次將收到訊息或一批訊息。
在Exactly-Once中,語義生產者與消費者一起將作為原子操作出現,它將作為一個單元進行操作。要麼釋出一次就被消耗掉,要麼中止。
在Kafka Stream中恰好一次
Kafka Stream消耗來自主題A的訊息,處理並將訊息釋出到主題B,並在釋出後使用commit(commit主要在後臺執行)將所有狀態儲存資料重新整理到磁碟。
在Kafka Stream中,一次完全是讀取過程寫入模式,可確保將這些操作視為原子操作。由於Kafka Stream可以滿足生產者,消費者和交易的需求,因此Kafka Stream附帶了特殊的引數processing.guarantee,它可以完全地_once或at_least_once使得不單獨處理所有引數變得容易。
Kafka Streams原子地更新使用者偏移量,本地狀態儲存,狀態儲存changelog主題和生產,以一起輸出所有主題。如果這些步驟中的任何一個失敗,則所有更改都將回滾。
processing.guarantee:確切地提供一次以下引數,您無需明確設定
- isolated.level = read_committed
- enable.idempotence = true
- MAX_IN_FLIGHT_REQUESTS_PER_CONNECTION = 5
相關文章
- Apache Kafka訊息傳遞策略ApacheKafka
- Kafka 精確一次語義Kafka
- Apache Kafka和Spring Boot的容錯和可靠訊息傳遞 – Arnold GalovicsApacheKafkaSpring Boot
- Kafka 訊息丟失與消費精確一次性Kafka
- Apache Kafka消費者再平衡 | TechMyTalkApacheKafka
- vue---元件間傳遞訊息(父子傳遞訊息,兄弟傳遞訊息)Vue元件
- kafka的至少一次和精確一次Kafka
- kafka精確一次語義EOS的原理深入剖析-kafka 商業環境實戰Kafka
- Chrome Extension 訊息傳遞Chrome
- Flutter中訊息傳遞Flutter
- Rabbitmq可靠訊息投遞,訊息確認機制MQ
- 傳送kafka訊息的shell指令碼Kafka指令碼
- 專為實時而構建:使用Apache Kafka進行大資料訊息傳遞 第1部分ApacheKafka大資料
- 專為實時而構建:使用Apache Kafka進行大資料訊息傳遞 第2部分ApacheKafka大資料
- flutter 訊息傳遞機制Flutter
- Handler訊息傳遞機制
- Kafka -- 訊息傳送儲存流程Kafka
- KMQ:基於Apache Kafka的可靠性訊息佇列MQApacheKafka佇列
- [精]--這一次,讓你徹底明白Java的值傳遞和引用傳遞!Java
- 以事務方式傳送 Kafka 訊息Kafka
- Spring Boot 參考指南(訊息傳遞)Spring Boot
- QNX學習 -- API之訊息傳遞API
- Java中用Aeron實現UDP訊息傳遞JavaUDP
- 基於WebSocket的實時訊息傳遞設計Web
- 【原創】訊息佇列的消費語義和投遞語義佇列
- RabbitMQ,RocketMQ,Kafka 事務性,訊息丟失和訊息重複傳送的處理策略MQKafka
- WIN32傳送自定義訊息Win32
- Kafka 偏移量管理實現精確一次語義在Spark&Flink中的技術實踐-kafka商業應用實戰KafkaSpark
- android 訊息傳遞機制進階EventBus的深入探究Android
- Pulsar 入門實戰(1)--Pulsar 訊息傳遞
- NATS訊息傳遞與REST效能比較 | VinsguruREST
- Android之Handler訊息傳遞機制詳解Android
- Kafka訊息佇列Kafka佇列
- 分散式訊息Kafka分散式Kafka
- kafka 訊息佇列Kafka佇列
- 又傳來猝死訊息,生命只有一次
- Python程式專題8:分佈叢集的訊息傳遞Python
- .NET 8 中利用 MediatR 實現高效訊息傳遞