Řízení souběžnosti

Rozdílová Lake poskytuje pro transakce kyselin záruky mezi čtením a zápisy. To znamená, že:

  • Více modulů pro zápis v několika clusterech může současně upravovat oddíl tabulky a zobrazit konzistentní zobrazení snímků tabulky a pro tyto zápisy bude k dispozici sériové pořadí.
  • Čtenáři budou dál zobrazovat konzistentní zobrazení snímků tabulky, ve které byla úloha Azure Databricks spuštěná, i když se tabulka během úlohy upraví.

Řízení optimistické souběžnosti

Rozdílový Lake používá optimistické řízení souběžnosti k poskytování transakčních záruk mezi zápisy. V rámci tohoto mechanismu zapisuje funguje ve třech fázích:

  1. Přečtěte si: čtení (v případě potřeby) nejnovější dostupnou verzi tabulky, která určuje, které soubory je třeba upravit (tj. přepsané).
  2. Zápis: fáze všech změn pomocí zápisu nových datových souborů.
  3. Ověřit a potvrdit: před potvrzením změn zkontroluje, zda jsou navrhované změny v konfliktu s jinými změnami, které mohly být souběžně potvrzeny od čtení snímku. Pokud nedojde k žádnému konfliktu, všechny připravené změny se potvrdí jako nový snímek se správou verzí a operace zápisu bude úspěšná. Pokud však dojde ke konfliktům, operace zápisu se nezdařila s výjimkou souběžné úpravy místo poškození tabulky, která by byla provedena s operací zápisu v tabulce Parquet.

Úroveň izolace tabulky určuje, do jaké míry musí být transakce izolovaná od úprav provedených souběžnými operacemi. Informace o úrovních izolace podporovaných rozdílovým Lake Lake na Azure Databricks najdete v tématu úrovně izolace.

Konflikty při zápisu

Následující tabulka popisuje, které páry operací zápisu můžou kolidovat v každé úrovni izolace.

INSERT AKTUALIZOVAT, ODSTRANIT, SLOUČIT DO OPTIMIZE
INSERT Nejde kolidovat
AKTUALIZOVAT, ODSTRANIT, SLOUČIT DO Může kolidovat v serializaci, nemůže kolidovat v WriteSerializable Může kolidovat v serializovatelných a WriteSerializable
OPTIMIZE Nejde kolidovat Může kolidovat v serializovatelných a WriteSerializable Může kolidovat v serializovatelných a WriteSerializable

Zabránění konfliktům s využitím dělení a nesouvislých podmínek příkazů

Ve všech případech označených jako "může dojít ke konfliktu", bez ohledu na to, zda budou tyto dvě operace kolidovat, záleží na tom, zda pracují se stejnou sadou souborů. Tyto dvě sady souborů můžete oddělit tím, že tabulku vytvoříte na oddíly podle stejných sloupců, jako ty, které se používají v podmínkách operací. Například dva příkazy UPDATE table WHERE date > '2010-01-01' ... a DELETE table WHERE date < '2010-01-01' budou kolidovat, pokud tabulka není rozdělená podle data, jak se může pokusit změnit stejnou sadu souborů. Rozdělení tabulky na oddíly date se vyhne konfliktu. Proto rozdělení tabulky podle podmínek, které se běžně používají v příkazu, může výrazně snížit konflikty. Vytváření oddílů tabulky podle sloupce s vysokou mohutnost ale může vést k dalším problémům s výkonem kvůli velkému počtu podadresářů.

Výjimky při konfliktech

Pokud dojde ke konfliktu transakcí, zobrazí se některá z následujících výjimek:

ConcurrentAppendException

K této výjimce dojde, když souběžná operace přidává soubory do stejného oddílu (nebo kdekoli v nerozdělené tabulce), které vaše operace načítá. Přidávání souborů může být způsobeno INSERT DELETE UPDATE operacemi,, nebo MERGE .

S výchozí úrovní izolace WriteSerializable soubory přidané INSERT operacemi Blind (tj. operace, které nevidomě přidávají data bez čtení jakýchkoli dat) nekolidují s žádnou operací, i když se dotkne stejného oddílu (nebo kdekoli v nerozdělené tabulce). Pokud je úroveň izolace nastavená na Serializable , může dojít ke konfliktu neslepých připojení.

Tato výjimka je často vyvolána během souběžných DELETE UPDATE operací, nebo MERGE . I když souběžné operace mohou fyzicky aktualizovat různé adresáře oddílů, jeden z nich může číst stejný oddíl, který souběžně aktualizuje druhý, což způsobuje konflikt. Tomu se můžete vyhnout tím, že v podmínkách operace rozřadíte explicitně oddělení. Představte si následující příklad.

// Target 'deltaTable' is partitioned by date and country
deltaTable.as("t").merge(
    source.as("s"),
    "s.user_id = t.user_id AND s.date = t.date AND s.country = t.country")
  .whenMatched().updateAll()
  .whenNotMatched().insertAll()
  .execute()

Předpokládejme, že jste výše uvedený kód spustili souběžně pro různá data nebo země. Vzhledem k tomu, že každá úloha pracuje na nezávislém oddílu na cílové rozdílové tabulce, neočekáváte žádné konflikty. Podmínka ale není explicitně dostačující a může kontrolovat celou tabulku a může kolidovat se souběžnými operacemi s aktualizací všech ostatních oddílů. Místo toho můžete příkaz přepsat a přidat konkrétní datum a zemi do podmínky sloučení, jak je znázorněno v následujícím příkladu.

// Target 'deltaTable' is partitioned by date and country
deltaTable.as("t").merge(
    source.as("s"),
    "s.user_id = t.user_id AND s.date = t.date AND s.country = t.country AND t.date = '" + <date> + "' AND t.country = '" + <country> + "'")
  .whenMatched().updateAll()
  .whenNotMatched().insertAll()
  .execute()

Tato operace je teď v bezpečí souběžně s různými daty a zeměmi.

ConcurrentDeleteReadException

K této výjimce dojde, když souběžná operace odstranila soubor, který vaše operace přečte. Mezi běžné příčiny patří DELETE UPDATE operace, nebo, MERGE která přepisuje soubory.

ConcurrentDeleteDeleteException

K této výjimce dojde, když souběžná operace odstranila soubor, který vaše operace odstraní. To může být způsobeno tím, že dvě souběžné operace přepisují stejné soubory.

MetadataChangedException

K této výjimce dojde, když souběžná transakce aktualizuje metadata rozdílové tabulky. Běžné příčiny jsou ALTER TABLE operace nebo zápisy do tabulky rozdílů, které aktualizují schéma tabulky.

ConcurrentTransactionException

Pokud se dotaz streamování používající stejné umístění kontrolního bodu spouští několikrát souběžně a pokusí se zapisovat do tabulky rozdílů současně. Nikdy byste neměli mít dva dotazy streamování, které používají stejné umístění kontrolního bodu a běží současně.

ProtocolChangedException

Tato výjimka může nastat v následujících případech:

  • Když je tabulka rozdílů upgradována na novou verzi. Aby budoucí operace proběhla úspěšně, možná budete muset upgradovat rozdílovou verzi aplikace Lake Lake.
  • V případě, že více zapisovačů vytváří nebo nahrazuje tabulku současně.
  • V případě, že více zapisovačů zapisuje do prázdné cesty současně.

Další podrobnosti najdete v tématu Správa verzí tabulky .