kafka生產者冪等與事務

目錄

前言:

冪等

事務

總結:?

參考資料?


前言:

Kafka 消息交付可靠性保障以及精確處理一次語義的實現。

所謂的消息交付可靠性保障,是指 Kafka 對 Producer 和 Consumer 要處理的消息提供什么樣的承諾。常見的承諾有以下三種:

  • 最多一次(at most once):消息可能會丟失,但絕不會被重復發送。
  • 至少一次(at least once):消息不會丟失,但有可能被重復發送。
  • 精確一次(exactly once):消息不會丟失,也不會被重復發送。

目前,Kafka 默認提供的交付可靠性保障是第二種,即至少一次。?

? ?即只有 Broker 成功“提交”消息且 Producer 接到 Broker 的應答才會認為該消息成功發送。不過倘若消息成功“提交”,但 Broker 的應答沒有成功發送回 Producer 端(比如網絡出現瞬時抖動),那么 Producer 就無法確定消息是否真的提交成功了。因此,它只能選擇重試,也就是再次發送相同的消息。這就是 Kafka 默認提供至少一次可靠性保障的原因,不過這會導致消息重復發送。

大部分用戶還是希望消息只會被交付一次,這樣的話,消息既不會丟失,也不會被重復處理。或者說,即使 Producer 端重復發送了相同的消息,Broker 端也能做到自動去重。在下游 Consumer 看來,消息依然只有一條。?

? ? ? Kafka 是怎么做到精確一次的呢?簡單來說,這是通過兩種機制:冪等性(Idempotence)和事務(Transaction)。

冪等

? ?“冪等”這個詞原是數學領域中的概念,指的是某些操作或函數能夠被執行多次,但每次得到的結果都是不變的。

? ? 冪等性有很多好處,其最大的優勢在于我們可以安全地重試任何冪等性操作,反正它們也不會破壞我們的系統狀態。如果是非冪等性操作,我們還需要擔心某些操作執行多次對狀態的影響,但對于冪等性操作而言,我們根本無需擔心此事。

? ? ? ? 在 Kafka 中,Producer 默認不是冪等性的,但我們可以創建冪等性 Producer。它其實是 0.11.0.0 版本引入的新功能。在此之前,Kafka 向分區發送數據時,可能會出現同一條消息被發送了多次,導致消息重復的情況。在 0.11 之后,指定 Producer 冪等性的方法很簡單,僅需要設置一個參數即可,即 props.put(“enable.idempotence”, ture),或 props.put(ProducerConfig.ENABLE_IDEMPOTENCE_CONFIG, true)。

? ? ? ?enable.idempotence 被設置成 true 后,Producer 自動升級成冪等性 Producer,其他所有的代碼邏輯都不需要改變。Kafka 自動幫你做消息的重復去重。底層具體的原理很簡單,就是經典的用空間去換時間的優化思路,即在 Broker 端多保存一些字段。當 Producer 發送了具有相同字段值的消息后,Broker 能夠自動知曉這些消息已經重復了,于是可以在后臺默默地把它們“丟棄”掉。當然,實際的實現原理并沒有這么簡單,但你大致可以這么理解。

? ? ? 看上去,冪等性 Producer 的功能很酷,使用起來也很簡單,僅僅設置一個參數就能保證消息不重復了,但實際上,我們必須要了解冪等性 Producer 的作用范圍。

? ? ? 首先,它只能保證單分區上的冪等性,即一個冪等性 Producer 能夠保證某個主題的一個分區上不出現重復消息,它無法實現多個分區的冪等性。次,它只能實現單會話上的冪等性,不能實現跨會話的冪等性。這里的會話,你可以理解為 Producer 進程的一次運行。當你重啟了 Producer 進程之后,這種冪等性保證就喪失了。

? ? ??那么你可能會問,如果我想實現多分區以及多會話上的消息無重復,應該怎么做呢?答案就是事務(transaction)或者依賴事務型 Producer。這也是冪等性 Producer 和事務型 Producer 的最大區別!

事務

?Kafka 的事務概念類似于我們熟知的數據庫提供的事務。在數據庫領域,事務提供的安全性保障是經典的 ACID,即原子性(Atomicity)、一致性 (Consistency)、隔離性 (Isolation) 和持久性 (Durability)。

各大主流數據庫廠商都比較統一。所謂的 read committed,指的是當讀取數據庫時,你只能看到已提交的數據,即無臟讀。同時,當寫入數據庫時,你也只能覆蓋掉已提交的數據,即無臟寫。

Kafka 自 0.11 版本開始也提供了對事務的支持,目前主要是在 read committed 隔離級別上做事情。它能保證多條消息原子性地寫入到目標分區,同時也能保證 Consumer 只能看到事務成功提交的消息。下面我們就來看看 Kafka 中的事務型 Producer。

事務型 Producer 能夠保證將消息原子性地寫入到多個分區中。這批消息要么全部寫入成功,要么全部失敗。另外,事務型 Producer 也不懼進程的重啟。Producer 重啟回來后,Kafka 依然保證它們發送消息的精確一次處理。

設置事務型 Producer 的方法也很簡單,滿足兩個要求即可:

  • 和冪等性 Producer 一樣,開啟 enable.idempotence = true。
  • 設置 Producer 端參數 transactional. id。最好為其設置一個有意義的名字

此外,你還需要在 Producer 代碼中做一些調整,如這段代碼所示:?

producer.initTransactions();
try {producer.beginTransaction();producer.send(record1);producer.send(record2);producer.commitTransaction();
} catch (KafkaException e) {producer.abortTransaction();
}

nitTransaction、beginTransaction、commitTransaction 和 abortTransaction,它們分別對應事務的初始化、事務開始、事務提交以及事務終止。

這段代碼能夠保證 Record1 和 Record2 被當作一個事務統一提交到 Kafka,要么它們全部提交成功,要么全部寫入失敗。實際上即使寫入失敗,Kafka 也會把它們寫入到底層的日志中,也就是說 Consumer 還是會看到這些消息。因此在 Consumer 端,讀取事務型 Producer 發送的消息也是需要一些變更的。修改起來也很簡單,設置 isolation.level 參數的值即可。當前這個參數有兩個取值:

  1. read_uncommitted:這是默認值,表明 Consumer 能夠讀取到 Kafka 寫入的任何消息,不論事務型 Producer 提交事務還是終止事務,其寫入的消息都可以讀取。很顯然,如果你用了事務型 Producer,那么對應的 Consumer 就不要使用這個值。
  2. read_committed:表明 Consumer 只會讀取事務型 Producer 成功提交事務寫入的消息。當然了,它也能看到非事務型 Producer 寫入的所有消息。

總結:?

冪等性 Producer 和事務型 Producer 都是 Kafka 社區力圖為 Kafka 實現精確一次處理語義所提供的工具,只是它們的作用范圍是不同的。冪等性 Producer 只能保證單分區、單會話上的消息冪等性;而事務能夠保證跨分區、跨會話間的冪等性。從交付語義上來看,自然是事務型 Producer 能做的更多。

不過,切記天下沒有免費的午餐。比起冪等性 Producer,事務型 Producer 的性能要更差,在實際使用過程中,我們需要仔細評估引入事務的開銷,切不可無腦地啟用事務。

參考資料?

14 | 冪等生產者和事務生產者是一回事嗎?-極客時間

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/38412.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/38412.shtml
英文地址,請注明出處:http://en.pswp.cn/news/38412.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

No view found for id 0x7f0901c3 for fragment解決以及線上bug排查技巧

情景再現 開發這么久,不知道你們是否也經歷過這樣的情況,測試或者用戶,反饋app閃退,結果你自己打開開發工具,去調試,一切正常,然后閃退還是存在,只是在開發環境中不能重現。這種情況…

boost下的asio異步高并發tcp服務器搭建

C 網絡編程 asio 使用總結 - 知乎 (zhihu.com) 基于Boost::asio的多線程異步TCP服務器&#xff0c;實現了io_service線程池&#xff0c;測試了1萬左右的并發訪問&#xff0c;讀寫無壓力_boost asio支持最大并發_E404的博客-CSDN博客 單線程 server.cpp #include <cstdlib&g…

【ARM 嵌入式 編譯系列 11.1 -- GCC __attribute__((aligned(x)))詳細介紹】

文章目錄 __attribute__((aligned(x)))詳細介紹其它對齊方式 上篇文章&#xff1a;ARM 嵌入式 編譯系列 11 – GCC attribute&#xff08;(packed)&#xff09;詳細介紹 attribute((aligned(x)))詳細介紹 __attribute__((aligned(x))) 是 GCC 編譯器的一個特性&#xff0c;它可…

SpringBoot代理訪問本地靜態資源400 404

SpringBoot代理訪問靜態資源400 404 背景&#xff1a;pdf文件上傳到linux服務器上&#xff0c;使用SpringBoot代理訪問問題&#xff1a;訪問過程中可能會出現400、404問題 前提&#xff1a;保證有文件&#xff0c;并且文件路徑正確 SpringBoot如何配置靜態資源代理&#xff0…

Flutter實現倒計時功能,秒數轉時分秒,然后倒計時

Flutter實現倒計時功能 發布時間&#xff1a;2023/05/12 本文實例為大家分享了Flutter實現倒計時功能的具體代碼&#xff0c;供大家參考&#xff0c;具體內容如下 有一個需求&#xff0c;需要在頁面進行顯示倒計時&#xff0c;倒計時結束后&#xff0c;做相應的邏輯處理。 實…

Antd的日期選擇器中文化配置

當你使用antd的日期選擇器后&#xff0c;你會發現日期什么都是英文的&#xff1a;即便你已經在項目中配置了中文化&#xff1a; 我確實已經配置了中文化&#xff1a; 但是為啥沒生效&#xff1f;官網回答&#xff1a;FAQ - Ant Design dayjs中文網&#xff1a; 安裝 | Day…

零拷貝詳解

1、在沒有DMA技術之前的I/O過程是這樣的&#xff1a; CPU發出對應的指令給磁盤控制器&#xff0c;然后返回磁盤控制器收到指令后&#xff0c;于是就開始準備數據&#xff0c;會把數據放入到磁盤控制器的內部緩沖區&#xff0c;然后產生中斷CPU收到中斷信號后&#xff0c;停下手…

華為OD機試-5鍵鍵盤的輸出

題目描述 【5鍵鍵盤的輸出】有一個特殊的 5鍵鍵盤&#xff0c;上面有 a,ctrl-c,ctrl-x,ctrl-v,ctrl-a五個鍵。 a鍵在屏幕上輸出一個字母 a; ctrl-c將當前選擇的字母復制到剪貼板; ctrl-x將當前選擇的 字母復制到剪貼板&#xff0c;并清空選擇的字母; ctrl-v將當前剪貼板里的字母…

HTML是什么?

HTML是什么&#xff1f; 超文本標記語言&#xff08;英語&#xff1a;HyperText Markup Language&#xff0c;簡稱&#xff1a;HTML&#xff09;是一種用于創建網頁的標準標記語言。 您可以使用 HTML 來建立自己的 WEB 站點&#xff0c;HTML 運行在瀏覽器上&#xff0c;由瀏覽器…

【業務功能篇63】Springboot聊聊 過濾器和攔截器

過濾器的場景&#xff1a;過濾器通常用于對數據或資源進行篩選、修改或轉換的場景。例如&#xff0c;在一個電子商務網站中&#xff0c;用戶進行商品搜索時&#xff0c;你可以使用過濾器來過濾特定的商品類別、價格范圍或其他條件&#xff0c;以便用戶僅看到符合篩選條件的結果…

人工智能時代的科學探索 | 《自然》評述

人工智能(AI)正越來越多地融入科學發現&#xff0c;以增強和加速研究&#xff0c;幫助科學家提出假設、設計實驗、收集和解釋大型數據集&#xff0c;并獲得僅靠傳統科學方法可能無法實現的洞察力。 過去十年間&#xff0c;AI取得了巨大的突破。其中就包括自監督學習和幾何深度學…

手機的發展歷史

目錄 一.人類的通信方式變化 二.手機對人類通信的影響 三.手機的發展過程 四.手機對現代人的影響 一.人類的通信方式變化 人類通信方式的變化是一個非常廣泛和復雜的話題&#xff0c;隨著技術的進步和社會的發展&#xff0c;人類通信方式發生了許多重大的變化。下面是一些主…

go mod使用最新提交依賴

例如一個項目在其中依賴了 github.com/linuxsuren/go-fake-runtime v0.0.1 go.mod內容&#xff1a; github.com/linuxsuren/go-fake-runtime v0.0.1 修改了github.com/linuxsuren/go-fake-runtime代碼&#xff0c;存在一個最新的commit hash值為25fa814c6232e545f5bce03bd…

【opencv】指定寬或高按比例縮放圖片 拼接圖片

指定寬或高按比例縮放圖片 import cv2def resize_by_ratio(image, widthNone, heightNone, intercv2.INTER_AREA):img_new_size None(h, w) image.shape[:2] # 獲得高度和寬度if width is None and height is None: # 如果輸入的寬度和高度都為空return image # 直接返回原圖…

應用程序運行報錯:First section must be [net] or [network]:No such file or directory

應用程序報錯環境&#xff1a; 在linux下&#xff0c;調用darknet訓練的模型&#xff0c;報錯&#xff1a;First section must be [net] or [network]:No such file or directory&#xff0c;并提示&#xff1a;"./src/utils.c:256: error: Assertion 0 failed." 如…

百日筑基篇——Pandas學習三(pyhton入門八)

百日筑基篇——Pandas學習三&#xff08;pyhton入門八&#xff09; 文章目錄 前言一、數據排序二、字符串處理三、數據合并方法1. merge方法2. concat方法 四、分組數據統計五、數據重塑1. stack2. pivot 總結 前言 上一篇文章介紹了一下pandas庫中的一些函數&#xff0c;而本…

MySQL數據類型

文章目錄 MySQL數據類型1. 數據類型分類2. 數值類型2.1 tinyint類型2.2 bit類型2.3 小數類型2.3.1 float2.3.2 decimal 2.4 字符串類型2.4.1 char2.4.2 varchar2.4.3 char和varchar比較 2.5 日期和時間類型2.6 enum和set MySQL數據類型 1. 數據類型分類 紅色標注是我主要講解…

【QT】 QFileQFileInfo文件操作

很高興在雪易的CSDN遇見你 &#xff0c;給你糖糖 歡迎大家加入雪易社區-CSDN社區云 前言 本文分享QT對文件的操作技術&#xff0c;希望對各位小伙伴有所幫助&#xff01; 感謝各位小伙伴的點贊關注&#xff0c;小易會繼續努力分享&#xff0c;一起進步&#xff01; 你的點…

linux中profile.d和profile的區別

profile.d在profile中加載 profile文件 PATH"/bin:/sbin:/usr/bin:/usr/sbin:/opt/bin:/opt/scripts:/soc/bin:/soc/scripts" LD_LIBRARY_PATH"/usr/local/lib:/usr/lib:/opt/lib:/soc/lib" export SSL_LDPATH/usr/local/lib/ export ZLIB_LDPATH/usr/lo…

appium默認60秒關閉應用的問題

問題&#xff1a;appium默認啟動一個應用的session過期時間是60秒到時間會自動停了剛啟動的應用&#xff0c;工作臺打印&#xff1a;info: [debug] We shut down because no new commands came in的日志 分析&#xff1a;--command-timeout 60 The default command timeout fo…