Úvod do CDC (Change Data Capture) Change Data Capture (CDC) je technika používaná ke sledování změn na úrovni řádků v databázových operacích (vkládání, aktualizace, mazání) a oznamování ostatních systémů v pořadí událostí. Ve scénářích zotavení po havárii CDC primárně synchronizuje data mezi primární a záložní databází, což umožňuje synchronizaci dat z primární do sekundární databáze v reálném čase. source ----------> CDC ----------> sink Apache SeaTunnel CDC SeaTunnel CDC nabízí dva typy synchronizace dat: : Přečte historická data z tabulky. Snapshot Read : Čte přírůstkové změny protokolu z tabulky. Přírůstkové sledování Synchronizace snímků bez zámku Fáze synchronizace snímků bez zámku je zdůrazněna, protože mnoho existujících platforem CDC, jako je Debezium, může během synchronizace historických dat uzamknout tabulky. Čtení snímků je proces synchronizace historických dat databáze. Základní průběh tohoto procesu je následující: storage -------------> splitEnumerator ---------- split ----------> reader ^ | | | \----------------- report -----------/ Dělené rozdělení (rozdělovač rozdělení) rozděluje data tabulky do více částí na základě specifikovaných polí (jako je ID tabulky nebo jedinečné klíče) a definované velikosti kroku. splitEnumerator Paralelní zpracování Každé rozdělení je přiřazeno jiné čtečce pro paralelní čtení. Jedna čtečka zabere jedno připojení. Zpětná vazba k události Po dokončení operace čtení pro rozdělení každý čtenář hlásí postup zpět do . Metadata pro rozdělení jsou poskytnuta následovně: splitEnumerator 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 Jakmile čtenář obdrží informace o rozdělení, vygeneruje příslušné příkazy SQL. Před spuštěním zaprotokoluje odpovídající pozici aktuálního rozdělení do protokolu databáze. Po dokončení aktuálního rozdělení čtenář hlásí postup do s následujícími údaji: splitEnumerator String splitId # Split ID Offset highWatermark # Log position corresponding to the split, for future validation Přírůstková synchronizace Fáze přírůstkové synchronizace začíná po fázi čtení snímku. V této fázi jsou veškeré změny ve zdrojové databázi zachyceny a synchronizovány se záložní databází v reálném čase. Tato fáze poslouchá databázový protokol (např. MySQL binlog). Přírůstkové sledování je obvykle jednovláknové, aby se zabránilo duplicitnímu stahování binlogu a snížilo se zatížení databáze. Proto se používá pouze jedna čtečka, která zabírá jediné připojení. data log -------------> splitEnumerator ---------- split ----------> reader ^ | | | \----------------- report -----------/ Ve fázi přírůstkové synchronizace jsou všechna rozdělení a tabulky z fáze snímku spojena do jediného rozdělení. Rozdělení metadat během této fáze je následující: 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 Pole jsou následující: CompletedSnapshotSplitInfo String splitId TableId tableId SeatunnelRowType splitKeyType Object splitStart Object splitEnd Offset watermark # Corresponds to the highWatermark in the report Rozdělení v přírůstkové fázi obsahuje vodoznak pro všechna rozdělení ve fázi snímku. Minimální vodoznak je vybrán jako výchozí bod pro přírůstkovou synchronizaci. Sémantika přesně jednou Ať už ve fázi čtení snímku nebo přírůstkového čtení, databáze se může také změnit kvůli synchronizaci. Jak garantujeme právě jednu dodávku? Fáze čtení snímku Ve fázi čtení snímku se například synchronizuje rozdělení, zatímco probíhají změny, jako je vložení řádku , aktualizace a vymazání . Pokud se během procesu čtení nepoužije žádná identifikace úlohy, může dojít ke ztrátě aktualizací. SeaTunnel to řeší takto: k3 k2 k1 Nejprve zkontrolujte pozici binlogu (nízký vodoznak) před čtením rozdělení. Čtení dat v rozsahu . split{start, end} Zaznamenání vysokého vodoznaku po přečtení. Je-li , data pro rozdělení se během čtení nezměnila. Pokud , došlo během zpracování ke změnám. V takovém případě SeaTunnel: high = low (high - low) > 0 Uložte rozdělená data do mezipaměti jako tabulku v paměti. Aplikujte změny z na v pořadí pomocí primárních klíčů k přehrání operací v tabulce v paměti. low watermark high watermark Nahlaste vysoký vodoznak. 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 Přírůstková fáze Před zahájením přírůstkové fáze SeaTunnel nejprve ověří všechna rozdělení z předchozího kroku. Mezi rozděleními mohou být data aktualizována, například pokud jsou mezi split1 a split2 vloženy nové záznamy, mohly by během fáze snímku chybět. K obnovení těchto dat mezi rozděleními se SeaTunnel řídí tímto přístupem: Ze všech rozdělených sestav najděte nejmenší vodoznak jako počáteční vodoznak, abyste mohli začít číst protokol. U každého přečteného záznamu protokolu zkontrolujte , abyste zjistili, zda byla data zpracována v nějakém rozdělení. Pokud ne, považuje se to za data mezi rozděleními a mělo by být opraveno. completedSnapshotSplitInfos Jakmile jsou všechna rozdělení ověřena, proces se přesune do úplné inkrementální fáze. |------------filter split2-----------------| |----filter split1------| data log -|-----------------------|------------------|----------------------------------|- log offset min watermark split1 watermark split2 watermark max watermark Kontrolní bod a pokračování A co pozastavení a obnovení CDC? SeaTunnel používá algoritmus distribuovaných snímků (Chandy-Lamport): Předpokládejme, že systém má dva procesy, a , kde má tři proměnné a má tři proměnné . Počáteční stavy jsou následující: p1 p2 p1 X1 Y1 Z1 p2 X2 Y2 Z2 p1 p2 X1:0 X2:4 Y1:0 Y2:2 Z1:0 Z2:3 V tomto okamžiku zahájí globální snímek. nejprve zaznamená svůj stav procesu a poté odešle značku na . p1 p1 p2 Než značka dosáhne , pošle zprávu do . p2 p2 M p1 p1 p2 X1:0 -------marker-------> X2:4 Y1:0 <---------M---------- Y2:2 Z1:0 Z2:3 Po přijetí markeru zaznamená svůj stav a přijme zprávu . Protože již provedl lokální snímek, potřebuje pouze zaprotokolovat zprávu . Konečný snímek vypadá takto: p2 p1 M p1 M p1 M p2 X1:0 X2:4 Y1:0 Y2:2 Z1:0 Z2:3 V SeaTunnel CDC jsou značky odesílány všem čtenářům, děleným enumerátorům, zapisovačům a dalším uzlům, přičemž každý si zachovává svůj stav paměti.