Oracle、MySQL、およびSQL Serverなどのシナリオを同期するためにSeaTunnel CDC(Change Data Capture)を使用する生産環境における最近の実践に基づき、幅広いユーザーからのフィードバックと組み合わせて、SeaTunnelがCDCを実装するプロセスを理解するためにこの記事を書きました。 CDCの3段階 CDCのデータを読むプロセスは、3つの主要な段階に分けられます。 Snapshot(フルロード) バックフィール 増加 1.Snapshotステージ スナップショット段階の意味は非常に直感的です:現在のデータベーステーブルデータのスナップショットをとり、JDBC経由で完全なテーブルスキャンを実行します。 MySQL を例に考えると、現在の binlog 位置は、スナップショット中に記録されます。 SHOW MASTER STATUS; File Position Binlog_Do_DB Binlog_Ignore_DB Executed_Gtid_Set binlog.000011 1001373553 バンコク0011 1001373553 SeaTunnel は、ファイルと位置を . low watermark 注:これは一度だけ実行されるのではなく、SeaTunnelはスナップショットを加速するために独自のスピリットカットロジックを実装しています。 注:これは一度だけ実行されるのではなく、SeaTunnelはスナップショットを加速するために独自のスピリットカットロジックを実装しています。 MySQL Snapshot Splitting Mechanism(スプリット) グローバルパラレルは10であると仮定します。 SeaTunnel は最初にすべてのテーブルとその主要キー/ユニークキー範囲を分析し、適切な分割列を選択します。 snapshot.split.size = 8096 のデフォルトで、この列の最大値と最小値に基づいて分割されます。 大きなテーブルは、サブタスクリクエストの順序に従って10の並列チャンネルに割り当てられる数百のスプリットに切り分けることができます(全体的にバランスの取れた分布に向かう傾向があります)。 Table-level sequential processing (schematic): // Processing sequence: // 1. Table1 -> Generate [Table1-Split0, Table1-Split1, Table1-Split2] // 2. Table2 -> Generate [Table2-Split0, Table2-Split1] // 3. Table3 -> Generate [Table3-Split0, Table3-Split1, Table3-Split2, Table3-Split3] Split-level parallel allocation: // Allocation to different subtasks: // Subtask 0: [Table1-Split0, Table2-Split1, Table3-Split2] // Subtask 1: [Table1-Split1, Table3-Split0, Table3-Split3] // Subtask 2: [Table1-Split2, Table2-Split0, Table3-Split1] 各 Split は、例えば、範囲条件を持つクエリです。 SELECT * FROM user_orders WHERE order_id >= 1 AND order_id < 10001; 各スプリットは別々に、独自の低水印/高水印を記録する。 Crucial: 作らないでください。 あまりにも小さく、あまりにも多くのスプリットを持つことは必ずしも速くないし、スケジュールとメモリのオーバーヘッドは非常に大きい。 Practical Advice: split_size 2.バックフィールドステージ 頻繁に書き込まれているテーブルの完全なスナップショットを実行していると想像してください. When you read the 100th row, the data in the 1st row may already have been modified. If you only read the snapshot, the data you hold when you finish reading is actually "inconsistent" (part is old, part is new). Why is Backfill needed? The role of Backfill is to compensate for the "data changes that occurred during the snapshot" so that the data is eventually consistent. この段階の行動は主に構成の構成に依存します。 パラメータ exactly_once シンプルなスタイル( ) exactly_once = false これはデフォルトモードであり、論理は比較的単純で直接であり、メモリキャッシュを必要としません。 Direct Snapshot Emission:スナップショットデータを読み、キャッシュを入力することなく直接ダウンストリームに送信します。 Direct Log Emission: 同時に Binlog を読み、ダウンストリームで直接送信します。 可能な一貫性:中間(旧Aが最初に送信され、次に新Bが後押しされる)、下流がidepotent をサポートする限り(MySQLの REPLACE INTOのように)は、最終結果は一貫します。 2 次 次 次 ( ) exactly_once = true これはSeaTunnel CDCの最も印象的な部分であり、データが「決して失われず、繰り返されない」ことを保証する秘密です。 デドブレイクについて memory buffer (Buffer) 教師があなたに今クラスに何人いるかを数えるように頼むことを想像してください(スナップショットステージ)。しかし、クラスの生徒は非常に不快で、あなたが数えている間、人々は入って出ています(データの変更)。 Simple Explanation: SeaTunnelはこんな感じです。 最初に写真を撮る(スナップショット):クラスの人数を最初に数え、小さなノートブック(メモリバッファ)に記録してください。 Watch the Surveillance (Backfill):あなたが数えていた期間の監視ビデオ(Binlogログ)を取得します。 レコードを修正する(Merge): 監視が誰かが入って来ただけのことを示しているが、あなたがそれらを数えていない場合 -> 追加します。 監視が誰かが逃げ出したばかりのことを示している場合、しかしあなたは彼らを数えました -> 彼らを横断します。 監視が誰かが自分の服を変えたことを示す場合 -> 新しい服にレコードを変更します。 Submit Homework (Send): 訂正後、あなたの手にある小さなノートは完全に正確なリストです。 意味 Summary for Beginners: exactly_once = true "hold it in and don't send it until it's clearly verified." 利点:下流で受信されたデータは絶対にクリーンで、複製や混乱なし。 コスト: テーブルが特に大きい場合は、メモリが不足する可能性があります。 2.3 2つの重要な質問と答え なぜバックフィールド段階で READ イベントが起きないのか? Q1: Why is case READ: throw Exception READ イベントは、SeaTunnel 自身によって定義され、具体的に「ストックデータがスナップショットから読まれる」ことを表しています。 バックフィールド段階では、データベースの Binlog を読み取ります。Binlog は「追加、削除、および修正」を記録します(INSERT/UPDATE/DELETE)そして、「誰かがデータをクエリした」ことを記録しません。 したがって、バックフィールド段階で READ イベントを読み取った場合、コードの論理が混乱していることを意味します。 Q2: If it's placed in memory, can the memory hold it? Will it OOM? それはテーブル全体を記憶に置くのではありません: SeaTunnel は分割で処理します。 分割は小さい: デフォルトの分割には、わずか 8096 行のデータがあります。 使用後に捨てる:分割を処理した後、それを送信し、メモリをクリアし、次の分割を処理します。 メモリ占有量式 ≈ : Parallelism × Split size × Single row data size. 2.4 Key Detail: Watermark Alignment Between Multiple Splits ウォーターマーク 極めて重要な問題ですが、きちんと解決できなければ、 it will lead to data being either lost or repeated. Fast/Slow Runner 問題: 2 人の学生(Split A および Split B)が宿題(バックフィールドデータ)をコピーしていることを想像してください。 Plain Language Explanation: 学生A(速い):100ページにコピーし、10時に終了。 学生B(遅い):200ページにコピーし、10時05分に完成しました。 現在、教師(増加課題)は、コピーを終えた場所から新しいレッスンを教え続ける必要があります。 ページ 200: Student B から開始すると、学生 A のコンテンツが 100 ページから 200 ページ(10 時から 10 時05分の間に発生した)の間で欠落した場合、完全に失われます。 学生Aが接続されている場合、学生Bが「先生、私はすでにページ100から200にコンテンツをコピーしました!」と文句を言います。 SeaTunnelのソリューション:最初から始めて、あなたがすでに聞いたことについて耳を隠す: SeaTunnelは、 戦略: "Minimum Watermark Starting Point + Dynamic Filtering" スタートを決定する(遅いものに気をつける):教師は100ページからスタートすることを決定します(すべての分割の最小ウォーターマーク)。 Dynamic Filtering (do not listen to what has been heard): While the teacher is lecturing (reading Binlog), they hold a list: { A: 100, B: 200 }. 教師が150ページに到達したとき: リストを見て、それはA? 150 > 100,Aはそれを聞いていない、それを記録(送信)します。 リストを見て、それはB? 150 < 200、Bはすでにそれをコピーし、直接それを省略します(discard)。 フルスピードモード(誰もが聴き終わった):教師が201ページに到達し、誰もがすでにそれを聞いたことが分かったとき、彼らはもうリストを必要としません。 同 : 増加段階は、「スタートオフセット + 分割範囲 + 高いウォーターマーク」の組み合わせに従って厳密にフィルターします。 Summary in one sentence: exactly_once なし : 増加段階は、単純な「一定のスタートオフセットからの連続消費」になります。 exactly_once 3.増加段階 バックフィールド(for )またはスナップショットステージが終了すると、純粋な増加段階に入ります。 exactly_once = true MySQL: Binlog に基づく Oracle: redo/logminer をベースにします。 SQL Server: トランザクションログ/LSNに基づく。 PostgreSQL:WALに基づく。 増加段階のSeaTunnelの行動は、ネイティブ Debeziumに非常に近い: オフセット順にログを消費します。 各変更に対して INSERT/UPDATE/DELETE などのイベントを構築します。 exact_once = true の場合、offset と split 状態がチェックポイントに含まれて、エラー回復後の「exactly-once」セマンティクスを達成します。 4.概要 SeaTunnel CDCのコアデザイン哲学は、完璧なバランスを見つけることです。 そして "Fast" (parallel snapshots) "Stable" (data consistency). プロセス全体の主要なポイントを検討しましょう: Slicing (Split) は、並列加速の基礎です:大きなテーブルを小さなパーツに切断して、複数のトレードを同時に動作させます。 Snapshot は、ストックの移動を担当しています:歴史データを並行して読み取るためにシリーズを使用します。 バックフィールドは、ギャップを縫う責任があります:これは最も重要なステップです. It compensates for changes during the snapshot and eliminates duplicates using memory merging algorithms to Exactly-Once. Incremental はリアルタイムの同期に責任を負います:シームレスに Backfill ステージに接続し、データベースログを継続的に消費します。 この trilogy of 連携する役割は、 その中では、SeaTunnel CDCの本質を真にマスターすることです。 "Snapshot -> Backfill -> Incremental" "Watermarks"