Berdasarkan praktik terbaru di lingkungan produksi menggunakan SeaTunnel CDC (Change Data Capture) untuk menyinkronkan skenario seperti Oracle, MySQL, dan SQL Server, dan dikombinasikan dengan umpan balik dari berbagai pengguna, saya telah menulis artikel ini untuk membantu Anda memahami proses yang SeaTunnel menerapkan CDC. Tiga Tahap CDC Proses keseluruhan membaca data CDC dapat dibagi menjadi tiga tahap utama: Menggunakan Snapshot (Full load) Backlink Peningkatan Langkah 1 – Snapshot Arti dari tahap Snapshot sangat intuitif: ambil snapshot dari data tabel database saat ini dan lakukan pemindaian tabel penuh melalui JDBC. Mengambil MySQL sebagai contoh, posisi binlog saat ini dicatat selama snapshot: SHOW MASTER STATUS; File Position Binlog_Do_DB Binlog_Ignore_DB Executed_Gtid_Set binlog.000011 1001373553 Keterangan 0011 1001373553 SeaTunnel mencatat File dan Lokasi sebagai . low watermark Catatan: Ini tidak hanya dilakukan sekali, karena SeaTunnel telah menerapkan logika pemotongan split sendiri untuk mempercepat snapshot. Catatan: Ini tidak hanya dilakukan sekali, karena SeaTunnel telah menerapkan logika pemotongan split sendiri untuk mempercepat snapshot. Mekanisme Pembagian Snapshot MySQL (Split) Jika kita mengasumsikan paralelisme global adalah : 10. SeaTunnel akan terlebih dahulu menganalisis semua tabel dan rentang kunci utama / unik mereka dan memilih kolom pemisahan yang sesuai. Ini dibagi berdasarkan nilai maksimum dan minimum kolom ini, dengan default snapshot.split.size = 8096. Tabel besar dapat dipotong menjadi ratusan Splits, yang ditugaskan ke 10 saluran paralel oleh enumerator sesuai dengan urutan permintaan subtask (menuju distribusi seimbang secara keseluruhan). 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] Setiap Split sebenarnya adalah kueri dengan kondisi rentang, misalnya: SELECT * FROM user_orders WHERE order_id >= 1 AND order_id < 10001; Setiap Split secara terpisah mencatat watermark rendah / watermark tinggi sendiri. Crucial: Jangan membuat terlalu kecil; memiliki terlalu banyak Split tidak selalu lebih cepat, dan jadwal dan memori overhead akan sangat besar. Practical Advice: split_size Langkah 2: Backfill Stage Bayangkan Anda melakukan snapshot penuh dari tabel yang sering ditulis ke. Ketika Anda membaca baris ke-100, data di baris ke-1 mungkin sudah diubah. Jika Anda hanya membaca snapshot, data yang Anda simpan saat Anda selesai membaca sebenarnya "tidak konsisten" (bagian lama, bagian baru). 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. Perilaku tahap ini sebagian besar tergantung pada konfigurasi dengan parameter exactly_once 4.1 Perbedaan Modal ( ) exactly_once = false Ini adalah mode default; logika relatif sederhana dan langsung, dan tidak memerlukan caching memori: Direct Snapshot Emission: Membaca data snapshot dan mengirimkannya langsung ke bawah tanpa memasukkannya ke cache. Direct Log Emission: Membaca Binlog pada saat yang sama dan mengirimkannya langsung ke bawah. Konsistensi Kemungkinan: Meskipun akan ada duplikat di tengah (A lama dikirim pertama, kemudian B baru), selama downstream mendukung idempotent menulis (seperti MySQL REPLACE INTO), hasil akhir adalah konsisten. 4.2 Peraturan yang berlaku ( ) exactly_once = true Ini adalah bagian yang paling mengesankan dari SeaTunnel CDC, dan itu adalah rahasia untuk menjamin bahwa data "tidak pernah hilang, tidak pernah diulang." Untuk Deduplikasi memory buffer (Buffer) Bayangkan guru meminta Anda untuk menghitung berapa banyak orang yang ada di kelas saat ini (etape snapshot).Tetapi, siswa di kelas sangat membingungkan; sementara Anda menghitung, orang-orang berlari masuk dan keluar (perubahan data). Simple Explanation: SeaTunnel melakukannya seperti ini: Ambil Foto Pertama (Snapshot): Menghitung jumlah orang di kelas pertama dan catatnya di buku catatan kecil (buffer memori); tidak memberitahu utama (downstream) belum. Watch the Surveillance (Backfill): Dapatkan video pengawasan (Binlog log) untuk periode yang Anda hitung. Untuk memperbaiki catatan (merge) : Jika pengawasan menunjukkan seseorang baru datang, tetapi Anda tidak menghitung mereka -> tambahkan mereka. Jika pengawasan menunjukkan seseorang baru saja keluar, tetapi Anda menghitung mereka di -> menyeberang mereka. Jika pengawasan menunjukkan seseorang mengubah pakaian mereka -> ubah catatan untuk pakaian baru. Submit Homework (Send): Setelah koreksi, notebook kecil di tangan Anda adalah daftar yang benar-benar akurat; sekarang menyerahkan ke kepala. berarti Summary for Beginners: exactly_once = true "hold it in and don't send it until it's clearly verified." Keuntungan: Data yang diterima downstream benar-benar bersih, tanpa duplikat atau kekacauan. Biaya: Karena harus "ditahan," perlu mengkonsumsi beberapa memori untuk menyimpan data. 2.3 Dua Pertanyaan dan Jawaban Utama Mengapa tidak ada acara READ selama tahap Backfill? Q1: Why is case READ: throw Exception Acara READ didefinisikan oleh SeaTunnel sendiri, secara khusus untuk mewakili "data stok yang dibaca dari snapshot." Tahap Backfill membaca Binlog dari database. Binlog hanya mencatat "penambahan, penghapusan, dan modifikasi" (INSERT/UPDATE/DELETE) dan tidak pernah mencatat "seseorang menanyakan sepotong data." Oleh karena itu, jika Anda membaca peristiwa READ selama tahap Backfill, itu berarti logika kode bingung. Q2: If it's placed in memory, can the memory hold it? Will it OOM? Ini tidak menempatkan seluruh tabel ke dalam memori: SeaTunnel memproses dengan memisahkan. Split kecil: Split default hanya memiliki 8096 baris data. Membuang setelah digunakan: Setelah memproses split, kirimkannya, membersihkan memori, dan memproses berikutnya. Memory Occupation Formula ≈ : Parallelism × Split size × Single row data size. 2.4 Detail Kunci: Watermark Alignment Antara Banyak Splits Ini adalah masalah yang sangat tersembunyi tetapi sangat penting. jika tidak ditangani dengan baik, it will lead to data being either lost or repeated. The Fast/Slow Runner Problem: Bayangkan dua siswa (Split A dan Split B) sedang menyalin tugas rumah (Backfill data). Plain Language Explanation: Mahasiswa A (cepat): Dibocorkan ke halaman 100 dan selesai pada pukul 10:00. Siswa B (lambat): Dibocorkan ke halaman 200 dan baru selesai pada 10:05. Sekarang, guru (Tugas Incremental) perlu terus mengajarkan pelajaran baru (membaca Binlog) dari mana mereka selesai menyalin. Jika dimulai dari halaman 200: Siswa B terhubung, tetapi konten Siswa A hilang antara halaman 100 dan 200 (yang terjadi antara 10:00 dan 10:05) benar-benar hilang. Jika dimulai dari halaman 100: Siswa A terhubung, tetapi Siswa B akan mengeluh: "Guru, saya sudah menyalin konten dari halaman 100 ke 200!" Solusi SeaTunnel: Mulai dari awal dan tutup telinga Anda untuk apa yang telah Anda dengar: SeaTunnel mengadopsi Strategi yang : "Minimum Watermark Starting Point + Dynamic Filtering" Tentukan Start (menjaga yang lambat): Guru memutuskan untuk memulai dari halaman 100 (tanda air minimum di antara semua split). Filter Dinamis (jangan mendengarkan apa yang telah didengar): Sementara guru sedang mengajar (menulis Binlog), mereka memegang daftar: { A: 100, B: 200 }. Ketika guru mencapai halaman 150: Lihat daftar; apakah itu untuk A? 150 > 100, A belum mendengarnya, catatnya (mengirimkan). Lihat daftar; apakah itu untuk B? 150 < 200, B sudah menyalinnya, melewatkannya langsung (discard). Mode kecepatan penuh (semua orang telah selesai mendengarkan): Ketika guru mencapai halaman 201 dan menemukan semua orang telah mendengarnya, mereka tidak lagi membutuhkan daftar. dengan : Tahap incremental secara ketat menyaring sesuai dengan kombinasi "start offset + split range + watermark tinggi." Summary in one sentence: exactly_once tanpa Tahap incremental menjadi "konsumsi berurutan dari offset awal tertentu." exactly_once 3. tahap peningkatan Setelah penutupan (untuk ) atau fase Snapshot berakhir, ia memasuki tahap incremental murni: exactly_once = true MySQL: Berbasis pada binlog. Oracle: Berbasis pada redo / logminer. SQL Server: Berdasarkan log transaksi / LSN. PostgreSQL: Berdasarkan pada WAL. Perilaku SeaTunnel di tahap incremental sangat dekat dengan Debezium asli: Konsumsi log dalam urutan offset. Membangun peristiwa seperti INSERT/UPDATE/DELETE untuk setiap perubahan. Ketika exactly_once = true, status offset dan split dimasukkan ke dalam checkpoint untuk mencapai semantik "precisely-once" setelah pemulihan kegagalan. 4) Pendekatan Filosofi desain inti SeaTunnel CDC adalah menemukan keseimbangan yang sempurna antara dan "Fast" (parallel snapshots) "Stable" (data consistency). Mari kita periksa titik-titik utama dari seluruh proses: Slicing (Split) adalah dasar dari akselerasi paralel: memotong tabel besar menjadi potongan-potongan kecil untuk memungkinkan beberapa thread bekerja secara bersamaan. Snapshot bertanggung jawab untuk bergerak stok: Menggunakan potongan-potongan untuk membaca data historis secara paralel. Backfill bertanggung jawab untuk menjahit celah-celah: Ini adalah langkah yang paling penting. ini mengkompensasi perubahan selama snapshot dan menghilangkan duplikat menggunakan algoritma penggabungan memori untuk mencapai Exactly-Once. Incremental bertanggung jawab untuk sinkronisasi real-time: terhubung dengan lancar ke tahap Backfill dan terus-menerus mengkonsumsi log database. Untuk memahami trilogi ini Peran koordinasi dari Di dalamnya adalah untuk benar-benar menguasai esensi SeaTunnel CDC. "Snapshot -> Backfill -> Incremental" "Watermarks"