Ang Change Data Capture (CDC) ay isang pamamaraan na ginagamit upang subaybayan ang mga pagbabago sa antas ng row sa mga pagpapatakbo ng database (mga pagpapasok, pag-update, pagtanggal) at abisuhan ang iba pang mga system sa pagkakasunud-sunod ng mga kaganapan. Sa mga sitwasyon sa pagbawi ng kalamidad, pangunahing sini-synchronize ng CDC ang data sa pagitan ng pangunahin at backup na database, na nagpapagana ng real-time na pag-sync ng data mula sa pangunahin hanggang sa pangalawang database.
source ----------> CDC ----------> sink
Nag-aalok ang SeaTunnel CDC ng dalawang uri ng pag-synchronize ng data:
Ang lock-free snapshot synchronization phase ay binibigyang-diin dahil maraming umiiral na mga platform ng CDC, gaya ng Debezium, ang maaaring mag-lock ng mga talahanayan sa panahon ng makasaysayang pag-synchronize ng data. Ang pagbabasa ng snapshot ay ang proseso ng pag-synchronize ng makasaysayang data ng database. Ang pangunahing daloy ng prosesong ito ay ang mga sumusunod:
storage -------------> splitEnumerator ---------- split ----------> reader ^ | | | \----------------- report -----------/
Split Partitioning
splitEnumerator
(split distributor) ay naghahati sa data ng talahanayan sa maraming hati batay sa mga tinukoy na field (gaya ng table ID o mga natatanging key) at tinukoy na laki ng hakbang.
Parallel Processing
Ang bawat split ay itinalaga sa ibang reader para sa parallel reading. Ang nag-iisang mambabasa ay sasakupin ang isang koneksyon.
Feedback sa Kaganapan
Pagkatapos makumpleto ang read operation para sa isang split, ang bawat reader ay nag-uulat ng progreso pabalik sa splitEnumerator
. Ang metadata para sa split ay ibinigay tulad ng sumusunod:
String splitId # Routing ID TableId tableId # Table ID SeatunnelRowType splitKeyType # The type of field used for partitioning Object splitStart # Start point of the partition Object splitEnd # End point of the partition
Kapag natanggap ng mambabasa ang split information, bubuo ito ng naaangkop na mga SQL statement. Bago magsimula, ini-log nito ang kaukulang posisyon ng kasalukuyang split sa log ng database. Pagkatapos makumpleto ang kasalukuyang split, ang mambabasa ay nag-uulat ng pag-unlad sa splitEnumerator
na may sumusunod na data:
String splitId # Split ID Offset highWatermark # Log position corresponding to the split, for future validation
Magsisimula ang yugto ng incremental na pag-synchronise pagkatapos ng yugto ng pagbasa ng snapshot. Sa yugtong ito, ang anumang mga pagbabagong nagaganap sa source database ay kinukuha at isi-synchronize sa backup na database sa real time. Ang bahaging ito ay nakikinig sa database log (hal., MySQL binlog). Ang incremental na pagsubaybay ay karaniwang single-threaded upang maiwasan ang mga duplicate na paghila ng binlog at bawasan ang pag-load ng database. Samakatuwid, isang mambabasa lamang ang ginagamit, na sumasakop sa isang solong koneksyon.
data log -------------> splitEnumerator ---------- split ----------> reader ^ | | | \----------------- report -----------/
Sa yugto ng incremental na pag-synchronize, lahat ng mga hati at talahanayan mula sa yugto ng snapshot ay pinagsama sa isang solong hati. Ang split metadata sa yugtong ito ay ang mga sumusunod:
String splitId Offset startingOffset # The lowest log start position among all splits Offset endingOffset # Log end position, or "continuous" if ongoing, eg, in the incremental phase List<TableId> tableIds Map<TableId, Offset> tableWatermarks # Watermark for all splits List<CompletedSnapshotSplitInfo> completedSnapshotSplitInfos # Snapshot phase split details
Ang mga field ng CompletedSnapshotSplitInfo
ay ang mga sumusunod:
String splitId TableId tableId SeatunnelRowType splitKeyType Object splitStart Object splitEnd Offset watermark # Corresponds to the highWatermark in the report
Ang split sa incremental phase ay naglalaman ng watermark para sa lahat ng split sa snapshot phase. Ang minimal na watermark ay pinili bilang panimulang punto para sa incremental na pag-synchronize.
Sa snapshot read man o incremental read phase, maaaring magbago din ang database para sa pag-synchronize. Paano namin ginagarantiyahan ang eksaktong isang paghahatid?
Sa snapshot read phase, halimbawa, ang isang split ay sini-synchronize habang ang mga pagbabago ay nangyayari, tulad ng pagpasok ng isang row k3
, isang update sa k2
, at isang pagtanggal ng k1
. Kung walang gagamiting pagkilala sa gawain sa panahon ng proseso ng pagbabasa, maaaring mawala ang mga update. Pinangangasiwaan ito ng SeaTunnel sa pamamagitan ng:
split{start, end}
.
Kung high = low
, hindi nagbago ang data para sa split habang binabasa. Kung (high - low) > 0
, naganap ang mga pagbabago sa panahon ng pagproseso. Sa ganoong kaso, ang SeaTunnel ay:
low watermark
hanggang sa high watermark
sa pagkakasunud-sunod, gamit ang mga pangunahing key upang i-replay ang mga operasyon sa in-memory na talahanayan.
insert k3 update k2 delete k1 | | | vvv bin log --|---------------------------------------------------|-- log offset low watermark high watermark CDC reads: k1 k3 k4 | Replays v Real data: k2 k3' k4
Bago simulan ang incremental phase, pinapatunayan muna ng SeaTunnel ang lahat ng split mula sa nakaraang hakbang. Sa pagitan ng mga hati, maaaring ma-update ang data, halimbawa, kung ang mga bagong tala ay ipinasok sa pagitan ng split1 at split2, maaaring mapalampas ang mga ito sa yugto ng snapshot. Para mabawi ang data na ito sa pagitan ng mga split, sinusunod ng SeaTunnel ang diskarteng ito:
completedSnapshotSplitInfos
upang makita kung ang data ay naproseso sa anumang hati. Kung hindi, ito ay itinuturing na data sa pagitan ng mga hati at dapat na itama.
|------------filter split2-----------------| |----filter split1------| data log -|-----------------------|------------------|----------------------------------|- log offset min watermark split1 watermark split2 watermark max watermark
Paano ang tungkol sa pag-pause at pagpapatuloy ng CDC? Gumagamit ang SeaTunnel ng distributed snapshot algorithm (Chandy-Lamport):
Ipagpalagay na ang system ay may dalawang proseso, p1
at p2
, kung saan p1
ay may tatlong variable X1 Y1 Z1
at p2
ay may tatlong variable X2 Y2 Z2
. Ang mga paunang estado ay ang mga sumusunod:
p1 p2 X1:0 X2:4 Y1:0 Y2:2 Z1:0 Z2:3
Sa puntong ito, p1
ay nagpasimula ng isang pandaigdigang snapshot. Inirerekord muna p1
ang estado ng proseso nito, pagkatapos ay nagpapadala ng marker sa p2
.
Bago maabot ng marker p2
, p2
ay nagpapadala ng mensahe M
sa p1
.
p1 p2 X1:0 -------marker-------> X2:4 Y1:0 <---------M---------- Y2:2 Z1:0 Z2:3
Sa pagtanggap ng marker, itinatala ng p2
ang estado nito, at tinatanggap p1
ang mensaheng M
. Dahil nagsagawa na ng lokal na snapshot p1
, kailangan lang nitong i-log ang mensaheng M
. Ang huling snapshot ay ganito ang hitsura:
p1 M p2 X1:0 X2:4 Y1:0 Y2:2 Z1:0 Z2:3
Sa SeaTunnel CDC, ang mga marker ay ipinapadala sa lahat ng mga mambabasa, mga split enumerator, mga manunulat, at iba pang mga node, na pinapanatili ng bawat isa ang katayuan ng memorya nito.