Flink CDC如何保障數據的一致性

Flink CDC如何保障數據的一致性

前言

在大規模流處理中,故障是無可避免的。機器會宕機,網絡會抖動。一個可靠的流處理引擎不僅要能高效地處理數據,更要在遇到這些故障時,保證計算結果的正確性。Apache Flink 正是因其強大的容錯機制一致性保障而聞名。

本文將深入探討 Flink 如何實現其核心的精確一次(Exactly-Once) 狀態一致性,并分析在與外部系統交互時,如何結合冪等性來實現端到端的精確一次語義。


一、從最多一次到精確一次

在流處理中,我們通常關心三種一致性語義:

  • At-Most-Once(最多一次): 消息可能丟失,但絕不會重復處理。
  • At-Least-Once(至少一次): 消息可能重復處理,但絕不會丟失。
  • Exactly-Once(精確一次): 消息肯定被處理且只被處理一次,仿佛故障從未發生。

Flink 的核心優勢在于其原生支持了狀態層面的精確一次語義。這意味著 Flink 內部維護的計數器、窗口狀態或用戶自定義狀態在故障恢復后都能保持絕對正確。


二、 分布式快照cp

Flink 實現精確一次的核心機制是基于 Chandy-Lamport 分布式快照算法的 檢查點(Checkpoint)

1. 什么是 checkpoint?

Checkpoint 是 Flink 應用在某個時間點的全局一致性快照,它包含了:

  • 所有算子(Operator)的狀態(如 sum() 的累加值)。
  • 所有數據源(Source)的讀取位置(如 Kafka 的 Offset)。
  • 所有正在傳輸中的數據記錄

這個快照會被持久化到一個可靠的分布式存儲系統(如 HDFS、S3)中。

2. 核心原理:屏障(Barrier)

JobManager(主節點)會定期觸發 Checkpoint。它向所有 Source 算子發送一個特殊的標記,稱為 Checkpoint Barrier

  • 廣播與對齊: Source 算子收到 Barrier 后,會立即快照自己的狀態(記錄當前 Offset),然后將 Barrier 廣播給下游所有算子。下游算子需要收到所有輸入流的 Barrier 后,才會對自己的狀態做快照。這個“等待所有 Barrier 到達”的過程稱為對齊,它是實現精確一次的關鍵。
  • 異步快照: 狀態快照是異步執行的,這意味著算子在做快照時,仍然可以處理數據,幾乎不影響性能。
  • 確認完成: 每個算子完成自己的快照后,會向 JobManager 發送確認(Ack)。當所有算子都確認后,這次 Checkpoint 才被視為全局完成。

3. 故障恢復:時光倒流

當發生故障時(如某個 TaskManager 宕機),Flink 的容錯機制會自動執行:

  1. 自動檢測: JobManager 檢測到故障,暫停整個作業。
  2. 狀態回滾: JobManager 找到最近一次成功的 Checkpoint
  3. 重新部署: 重啟整個作業拓撲,并將所有算子的狀態重置到 Checkpoint 記錄的那個時間點。
  4. 重置源: 通知所有 Source 算子,從 Checkpoint 中記錄的 Offset 開始重新消費數據。

通過這一機制,從上一個 Checkpoint 完成到故障發生之間所處理的所有數據及其產生的所有狀態變更,都被“回滾”了。系統仿佛進行了一次時光倒流,然后從那個保存點重新開始處理,從而保證了內部狀態的精確一次。


三、 端到端的精確一次

上述的 Checkpoint 機制完美保證了 Flink 內部狀態的精確一次。然而,一個完整的流處理應用通常包含:

  • 輸入源(Source): 如 Kafka, Pulsar
  • 處理邏輯(Flink Job)
  • 輸出匯(Sink): 如 MySQL, Elasticsearch, Kafka, HBase

要保證端到端(End-to-End) 的精確一次,就必須確保數據從被源讀取,到處理,再到最終寫入輸出匯的整個過程中,即使發生故障,結果也是精確一次的。

這需要外部系統也參與到 Flink 的分布式快照事務中來。Flink 通過 兩階段提交協議(Two-Phase Commit Protocol, 2PC) 來實現這一點。

兩階段提交 Sink 的工作原理

Flink 提供了通用的 TwoPhaseCommitSinkFunction 抽象類,用于實現支持 2PC 的 Sink。其工作流程與 Checkpoint 周期緊密綁定:

  1. 預提交階段(Pre-commit)

    • 當 Checkpoint Barrier 流過 Sink 算子時,Sink 會觸發 preCommit 操作。
    • 此時,Sink 會將當前批次的數據預先寫入外部系統,但不提交(例如,寫入 Kafka 的一個事務中,或者向數據庫寫入一條待提交的數據)。這個操作對外是不可見的。
    • Sink 將“預提交是否成功”的信息作為自己的狀態,保存到當前的 Checkpoint 中。這意味著對外部系統的“預提交”動作被原子性地包含在了 Flink 的 Checkpoint 里。
  2. 提交階段(Commit)

    • 當 JobManager 收到所有算子的 Ack,確認本次 Checkpoint 全局成功后,它會回調 Sink 算子的 commit 方法。
    • Sink 算子此時才正式提交之前預寫入的事務(例如,提交 Kafka 事務),讓數據真正對外可見。
  3. 中止階段(Abort)

    • 如果 Checkpoint 失敗(比如某個算子沒有成功快照),JobManager 會回調 Sink 算子的 abort 方法。
    • Sink 算子則中止之前預提交的事務(例如,回滾 Kafka 事務),清理掉預寫入的數據。

通過這種方式,Flink 確保了 Sink 端的數據輸出與自身的 Checkpoint 成功與否保持原子性:要么整個 Checkpoint 成功,數據對外可見;要么整個 Checkpoint 失敗,數據被完全撤銷。


四、 冪等性

兩階段提交協議雖然強大,但也有一些缺點:

  • 協議開銷: 預提交、提交、中止等操作需要與外部系統進行多輪交互。
  • 外部系統支持: 要求外部系統必須提供事務支持(如 Kafka 0.11+),這并非所有系統都具備。

在這種情況下,冪等性(Idempotence) 提供了一個更輕量級、更簡單的替代方案。

什么是冪等性?

冪等性是指:一個操作被執行一次與被執行多次,對系統產生的副作用(Side Effect)是相同的。

一個經典的例子是:將某個賬戶的余額設置為 100 元。無論你執行這個操作一次、兩次還是一百次,最終的結果都是余額為 100 元。這是一個冪等操作。而將余額增加 100 元則不是冪等的。

如何利用冪等性實現精確一次?

如果我們的 Sink 操作是冪等的,那么 Flink 的“至少一次”語義就可以輕松達到“端到端的精確一次”效果。

  • 工作流程

    1. Flink 內部仍使用 Checkpoint 機制保證狀態是精確一次的。
    2. 在 Sink 端,我們設計一個冪等寫入器
    3. 當發生故障并從 Checkpoint 恢復時,某些數據可能會被重復處理重復寫入 Sink(即“至少一次”)。
    4. 但由于寫入操作是冪等的,即使同一批數據被寫了多次,結果也和只寫一次完全相同。從外部看,效果就是精確一次的。
  • 實現關鍵

    • 為每一條數據生成一個唯一標識符(如 UUID,或由 源Topic+分區+Offset 組成)。
    • 在寫入外部系統時,以這個唯一ID作為主鍵或唯一索引。
    • 當寫入時,如果發現相同ID的數據已存在,則執行覆蓋(UPDATE)或忽略(INSERT ... ON DUPLICATE KEY UPDATE)操作,而不是追加。

適用場景: 數據庫(如 MySQL, HBase, Redis)的 UPSERT 操作,或者任何支持基于主鍵的覆蓋寫入的系統。


五、 總結與對比

機制原理優點缺點適用場景
Flink 內部 Checkpoint分布式快照 + 狀態回滾原生支持,高效可靠只保障內部狀態Flink 應用內部
兩階段提交 (2PC)與 Checkpoint 綁定的預提交和提交真正的端到端精確一次,通用性強延遲較高,需要外部系統支持事務Kafka、支持事務的數據庫
冪等寫入利用操作的冪等性對抗日志重復實現簡單,延遲低,不要求事務需要設計唯一ID,只能用于支持冪等寫入的系統支持 UPSERT 的數據庫(MySQL, HBase, Redis)

結論

Flink 通過其精巧的分布式快照機制,為內部狀態提供了堅固的精確一次保障。當需要與外部世界交互時,我們可以根據外部系統的能力,靈活選擇兩階段提交冪等性方案來實現端到端的精確一次。

  • 如果外部系統支持事務,兩階段提交是最標準、最通用的選擇。
  • 如果外部系統支持冪等寫入(如多數數據庫),那么采用冪等性方案通常更簡單、更高效。

理解這兩種模式的原理和適用場景,是設計一個高可靠性、高一致性 Flink 流處理應用的關鍵。Flink 的強大之處在于,它為我們提供了這兩種強大的工具,以應對各種復雜的生產環境挑戰。

=========================================================

人生得意須盡歡,莫使金樽空對月!
__一個熱愛說唱的程序員。
今日份推薦音樂:楊宗緯/姚曉棠《我會好好的 (Live版)》

=========================================================

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

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

相關文章

Spring Boot 定時任務入門

1. 概述 在產品的色彩斑斕的黑的需求中,有存在一類需求,是需要去定時執行的,此時就需要使用到定時任務。例如說,每分鐘掃描超時支付的訂單,每小時清理一次日志文件,每天統計前一天的數據并生成報表&#x…

學習:uniapp全棧微信小程序vue3后臺(6)

26.實現描述評分標簽的雙向數據綁定 /pages/wallpaper/picadd Array.prototype.splice() splice() 方法就地移除或者替換已存在的元素和/或添加新的元素。 二次確認 展現 確認標簽 刪除標簽 溫故知新: 標簽: 關閉標簽 27.uni-data-select調用云端分類…

Azure Marketplace 和 Microsoft AppSource的區別

微軟的商業應用生態中,Azure Marketplace 和 Microsoft AppSource 是微軟并行的兩個主要“應用市場”(Marketplace),它們共同構成了微軟的“商業市場”(Commercial Marketplace)計劃,但服務的目…

完整實驗命令解析:從集群搭建到負載均衡配置(2)

一、環境準備與基礎網絡配置1.1 節點角色與網絡規劃節點角色主機名所屬網段IP 地址網關核心功能Web 服務器web110.1.8.0/2410.1.8.1110.1.8.10(后期調整為 10.1.8.20)部署 Nginx/HTTPD,提供 Web 服務Web 服務器web210.1.8.0/2410.1.8.1210.1.…

uniapp H5禁止微信瀏覽器長按出菜單,只針對圖片

一、問題描述 如圖:uni-image>img,img {pointer-events: none;-webkit-pointer-events: none;-ms-pointer-events: none;-moz-pointer-events: none; }uni-image::before {content: ;position: absolute;top: 0;bottom: 0;left: 0;right: 0;background: transpa…

【機器學習】 15 Gaussian processes

本章目錄 15 Gaussian processes 515 15.1 Introduction 515 15.2 GPs for regression 516 15.2.1 Predictions using noise-free observations 517 15.2.2 Predictions using noisy observations 518 15.2.3 Effect of the kernel parameters 519 15.2.4 Estimating the kern…

Vue加載速度優化,verder.js和element.js加載速度慢解決方法

1. 使用CDN 這里把常用的vue、vuex、elementui、echarts、axios都引入成cdn的方式 1、在index.html引入CDN 找到public/index.html在上方引入下邊的cdn。 [!NOTE] 引入script的時候,一定要把vue.js放到最上邊,最先引入,不然后邊的js加載會…

49.【.NET8 實戰--孢子記賬--從單體到微服務--轉向微服務】--擴展功能--集成網關--Refit跨服務調用

Refit是一個用于.NET平臺的REST庫,它可以將REST API轉換為實時類型安全的接口。通過Refit,我們可以輕松實現微服務之間的跨服務調用,使服務間通信變得更加簡單和類型安全。本文將介紹如何在我們的項目中使用Refit來實現微服務間的通信。 一、什么是Refit Refit是一個強大的REST…

日志ELK、ELFK、EFK

一.ELK架構Elasticsearch Logstash Kibana 數據庫日志處理日志顯示1.logstash的使用(1)input:輸入(2)filter:處理(3)output:輸出2.ELFK架構Filebeat-->Elasticsearc…

【CUDA進階】MMA分析Bank Conflict與Swizzle(下)

目錄前言1. bank conflict 分析2. 通過 padding 解決 bank conflict3. mma 搭配 wmma 實現矩陣乘法計算3.1 代碼實現3.2 補充:stmatrix_sync 函數分析3.3 補充:__shfl_sync 函數詳解4. swizzle 原理講解5. swizzle 實現思路講解結語下載鏈接參考前言 學習…

天氣查詢系統

項目要求 項目知識點 問題與解決 代碼分部 結果展示 項目要求 1.顯示天氣預報系統界面 2.系統可以通過選擇城市配置獲取不同城市天氣信息 3.查看實時的天氣信息 (當前溫度、最高溫度、最低溫度、當前濕度、最高濕度、最低濕度、風向、風力、風級等信息&#x…

三重積分的對稱性

文章目錄前言柱面球面前言 規律作息 柱面 太牛了。我完全看不懂。實際上就類似于極坐標系。 球面 看到這么多東西,我真害怕。今天是 8.30 ,不管 9.10 有沒有復習完概率的強化,我都一定要開始套卷,還有專業課的復習。?\phi?…

深入理解 RabbitMQ:從底層原理到實戰落地的全維度指南

引言: 本文總字數:約 18500 字預計閱讀時間:45 分鐘 為什么我們需要 RabbitMQ? 在當今分布式系統架構中,消息隊列已成為不可或缺的核心組件。想象一下,當你在電商平臺下單時,系統需要處理庫存…

寬帶有丟包,重傳高的情況怎么優化

寬帶丟包和重傳率高是一個非常影響網絡體驗的常見問題。它會導致游戲卡頓、視頻通話模糊、網頁加載慢等。別擔心,我們可以按照從易到難的順序,系統地排查和優化。請遵循以下步驟:第一步:基礎排查(自己動手,…

Kotlin 協程之Channel 的高階應用

前言 了解了 Channel 的基礎概念和基本使用 后,我們再來看一看 Channel 的特性以及高階應用。 Channel 是"熱流" 熱流概念 Channel 是熱流(Hot Stream),具備以下特性: 數據的生產和消費是兩套獨立的流程 …

PostgreSQL表空間(Tablespace)作用(管理數據庫對象的存儲位置)(pg_default、pg_global)

文章目錄**1. 靈活的數據存儲管理**- **邏輯與物理分離**:表空間為數據庫對象(如表、索引)提供了一個邏輯名稱與物理存儲路徑的映射。用戶無需直接操作底層文件路徑,只需通過表空間名稱管理數據。- **多數據庫共享表空間**&#x…

Ansible 核心運維場景落地:YUM 倉庫、SSH 公鑰、固定 IP 配置技巧

1:如何一次性驗證所有主機能否被 Ansible 訪問? 答:使用臨時命令:ansible all -m ansible.builtin.ping或驗證 sudo 是否正常:ansible all -m ansible.builtin.ping --become -K2:如何用 Ansible 統一配置…

rman導致的報錯ORA-27037: unable to obtain file status

有套3節點的11204集群環境,在db2上配置了rman備份,今天例行檢查時發現db1和db3上不定期有報錯,報錯如下:Control file backup creation failed:failure to open backup target file /u01/app/oracle/product/11.2.0/db_1/dbs/snap…

Kubernetes 與 GitOps 的深度融合實踐指南

前言:在云原生技術飛速發展的今天,Kubernetes(簡稱 K8s)已成為容器編排領域的事實標準,而 GitOps 作為一種基于 Git 的云原生運維理念,正與 K8s 深度融合,為企業實現自動化、可追溯、可審計的應…

REST-assured 接口測試編寫指南

REST-assured 簡介 REST-assured 是一個基于 Java 的 DSL(領域特定語言)庫,專門用于簡化 RESTful API 測試的編寫。它提供了流暢的 API 接口,使得測試代碼更加易讀易寫,支持 JSON 和 XML 等多種響應格式的驗證。 基本環…