Gebaseer op onlangse praktyke in produksie omgewings wat SeaTunnel CDC (Change Data Capture) gebruik om scenario's soos Oracle, MySQL en SQL Server te sinchroniseer, en gekombineer met terugvoer van 'n wye verskeidenheid gebruikers, het ek hierdie artikel geskryf om u te help verstaan hoe SeaTunnel die CDC implementeer. Die drie stadiums van die CDC Die algehele CDC data leesproses kan in drie hooffases verdeel word: Snapshot (die volledige lading) Die agtergrond toenemende 1 Stap van die snapshot Die betekenis van die Snapshot-stap is baie intuïtief: neem 'n snapshot van die huidige databasetabeldata en voer 'n volledige tabelskanning deur JDBC uit. Neem MySQL as 'n voorbeeld, die huidige binlog posisie word opgespoor tydens die snapshot: SHOW MASTER STATUS; File Position Binlog_Do_DB Binlog_Ignore_DB Executed_Gtid_Set binlog.000011 1001373553 Geskryf 0011 1001373553 SeaTunnel registreer die lêer en posisie as die . low watermark Opmerking: Dit word nie net een keer uitgevoer nie, want SeaTunnel het sy eie split-snipping-logika geïmplementeer om snapshots te versnel. Opmerking: Dit word nie net een keer uitgevoer nie, want SeaTunnel het sy eie split-snipping-logika geïmplementeer om snapshots te versnel. MySQL Snapshot Splitting Mechanisme (Split) As ons aanvaar dat die globale parallelisme 10 is: SeaTunnel sal eers al die tabelle en hul primêre sleutel / unieke sleutelbereiken analiseer en 'n toepaslike splitserkolom kies. Dit word verdeel op grond van die maksimum en minimum waardes van hierdie kolom, met 'n standaard van snapshot.split.size = 8096. Grote tabelle kan in honderde Splits gesny word, wat deur die nummerer aan 10 parallelle kanale toegewyd word volgens die volgorde van subtaakverzoeke (tendens na 'n gebalanseerde verspreiding in die algemeen). 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] Elke Split is eintlik 'n query met 'n bereik voorwaarde, byvoorbeeld: SELECT * FROM user_orders WHERE order_id >= 1 AND order_id < 10001; Elke Split registreer afsonderlik sy eie lae watermerk / hoë watermerk. Crucial: Moenie die te klein; te veel splits is nie noodwendig vinniger nie, en die beplanning en geheue oorhead sal baie groot wees. Practical Advice: split_size 2 Stap van agteruitgang Stel jou voor dat jy 'n volledige snapshot van 'n tabel maak wat dikwels geskryf word.Wanneer jy die 100ste ry lees, is die data in die 1ste ry dalk al verander.As jy net die snapshot lees, is die data wat jy hou wanneer jy klaar lees, eintlik "inkonsistent" (deel is ou, deel is nuut). 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. Die gedrag van hierdie stadium hang hoofsaaklik af van die konfigurasie van die Parameters van. exactly_once In die tweede helfte van die jaar ( ) exactly_once = false Dit is die standaardmodus; die logika is relatief eenvoudig en direk, en dit vereis nie geheue caching nie: Direct Snapshot Emission: Lees snapshot data en stuur dit direk af sonder om 'n cache in te voer. Direct Log Emission: Lees Binlog op dieselfde tyd en stuur dit direk downstream. Eventuele konsekwentheid: Alhoewel daar duplikate in die middel sal wees (oude A eerste gestuur, dan nuwe B), so lank as die downstream ondersteun idempotent skryf (soos MySQL se REPLACE INTO), is die uiteindelike resultaat konsekwent. In die tweede helfte van die jaar ( ) exactly_once = true Dit is die mees indrukwekkende deel van SeaTunnel CDC, en dit is die geheim om te waarborg dat data nooit verlore gaan nie, nooit herhaal word nie. vir die verdubbeling. memory buffer (Buffer) Stel jou voor dat die onderwyser jou vra om te tel hoeveel mense op die oomblik in die klas is (Snapshot-fase). Maar die studente in die klas is baie misluk; terwyl jy tel, loop mense in en uit (data verander). Simple Explanation: SeaTunnel doen dit so: Neem 'n Foto Eerst (Snapshot): Tel die aantal mense in die klas eerste en skryf dit in 'n klein notasboek (geheue buffer); vertel nie die hoof (downstream) nog nie. Kyk na die opsporing (Backfill): Vind die opsporing video (Binlog log) vir die tydperk wat jy tel. Korrigeer die rekords (Merge): As die toesig toon dat iemand net ingekom het, maar jy het hulle nie getel nie -> voeg hulle by. As die toesig toon dat iemand net uitgevlug het, maar jy hulle getel het -> kruis hulle uit. As die toesig toon dat iemand sy klere verander het -> verander die rekord na die nuwe klere. Stuur huiswerk (Stuur): Na die regstelling, die klein notasie in jou hand is 'n heeltemal akkurate lys; gee dit nou aan die hoof. betekenis Summary for Beginners: exactly_once = true "hold it in and don't send it until it's clearly verified." Voordeel: Die data wat hieronder ontvang word, is absoluut skoon, sonder dubbele of wanorde. Koste: Omdat dit "gehou" moet word, moet dit 'n bietjie geheue verbruik om die data te stoor. 2.3 Twee belangrike vrae en antwoorde Waarom is daar nie LEES gebeurtenisse tydens die Backfill fase nie? Q1: Why is case READ: throw Exception Die READ-gebeurtenis word deur SeaTunnel self gedefinieer, spesifiek om "voorraaddata van die snapshot te verteenwoordig." Die Backfill-stap lees die Binlog van die databasis. Binlog registreer slegs "aanvullings, verwyderings en veranderinge" (INSERT/UPDATE/DELETE) en registreer nooit "n mens het 'n stuk data gevra nie." As u dus 'n READ-gebeurtenis lees tydens die Backfill-fase, beteken dit dat die kode-logika verward is. Q2: If it's placed in memory, can the memory hold it? Will it OOM? Dit sit nie die hele tafel in die geheue nie: SeaTunnel prosesse deur splits. Split is klein: 'n standaard split het slegs 8096 reëls van data. Gooi weg na gebruik: Na die verwerking van 'n splitsing, stuur dit, skoonmaak die geheue en verwerk die volgende. Die formule van geheue besetting ≈ : Parallelisme × Split grootte × Enkele reeks data grootte. 2.4 Sleutel besonderhede: Watermerk afstemming tussen verskeie splitsing Dit is 'n baie verborge, maar uiters belangrike kwessie. it will lead to data being either lost or repeated. Die vinnig / stadig hardloop probleem: Stel jou voor dat twee studente (Split A en Split B) kopieer huiswerk (Backfill data). Plain Language Explanation: Student A (snel): Kopieer na bladsy 100 en voltooi om 10:00. Student B (langs): Kopieer na bladsy 200 en net klaar om 10:05. Nou moet die onderwyser (Incrementale taak) voortgaan om 'n nuwe les te leer (lees Binlog) van waaruit hulle die kopieer beëindig het. As vanaf bladsy 200: Student B verbind is, maar die inhoud Student A wat tussen bladsye 100 en 200 gemis is (wat tussen 10:00 en 10:05 gebeur het), is heeltemal verlore. As jy vanaf bladsy 100 begin: Student A is aangesloten, maar Student B klag: "Meester, ek het reeds die inhoud van bladsy 100 na 200 gekopieer!" SeaTunnel se Oplossing: Begin van die vroegste af en bedek jou ore vir wat jy reeds gehoor het: SeaTunnel neem 'n Die strategie: "Minimum Watermark Starting Point + Dynamic Filtering" Bepaal die begin (versorging vir die stadig): Die onderwyser besluit om vanaf bladsy 100 te begin (die minimum watermerk onder al die splits). Dinamiese Filtering (Moenie luister na wat gehoor is nie): Terwyl die onderwyser les (lees Binlog), hou hulle 'n lys: { A: 100, B: 200 }. Wanneer die onderwyser bladsy 150 bereik: Kyk na die lys; is dit vir A? 150 > 100, A het dit nie gehoor nie, registreer dit (stuur). Kyk na die lys; is dit vir B? 150 < 200, B het dit reeds gekopieer, skip dit reguit (discard). Volle spoedmodus (elkeen het gehoor voltooi): Wanneer die onderwyser bladsy 201 bereik en vind dat almal dit al gehoor het, het hulle die lys nie meer nodig nie. met : Die inkrementele stadium filtreer streng volgens die kombinasie van "begin offset + verdeel bereik + hoë watermerk." Summary in one sentence: exactly_once sonder : Die inkrementele stadium word 'n eenvoudige "sequentiële verbruik van 'n sekere aanvanklike offset." exactly_once Die toenemende stadium Na die terugvoer (vir ) of Snapshot stadium eindig, dit gaan in die suiwer inkrementele stadium: exactly_once = true MySQL: Gebaseer op binlog. Oracle: Gebaseer op redo / logminer. SQL Server: Gebaseer op transaksie log / LSN. PostgreSQL: Gebaseer op WAL. SeaTunnel se gedrag in die incrementele stadium is baie naby aan die inheemse Debezium: Dit word in offset volgorde gebruik. Konstrueer gebeurtenisse soos INSERT/UPDATE/DELETE vir elke verandering. Wanneer exact_once = waar is, word die offset- en split-toestand in die kontrolepunt ingesluit om "precies-een keer" semantiek na mislukking herstel te bereik. 4 Samenvatting Die kernontwerpfilosofie van SeaTunnel CDC is om die perfekte balans tussen en "Fast" (parallel snapshots) "Stable" (data consistency). Kom ons kyk na die sleutelpunte van die hele proses: Slicing (Split) is die basis van parallelle versnelling: Groot tafels in klein stukke sny om verskeie drade op dieselfde tyd te laat werk. Snapshot is verantwoordelik vir die beweeg van voorraad: Gebruik sny om historiese data in parallel te lees. Backfill is verantwoordelik vir die naai van die gapings: Dit is die mees kritieke stap.Dit kompenseer veranderinge tydens die snapshot en elimineer duplikate met behulp van geheue fusie algoritmes om Exactly-Once te bereik. Incremental is verantwoordelik vir real-time sinchronisasie: naadloos verbind tot die Backfill-fases en voortdurend verbruik databasislogs. Om hierdie trilogie van Die koördinerende rol van in dit is om die essensie van SeaTunnel CDC werklik te beheer. "Snapshot -> Backfill -> Incremental" "Watermarks"