Megosztás a következőn keresztül:


Elkülönítési szintek és írási ütközések az Azure Databricksben

A tábla elkülönítési szintje határozza meg, hogy a tranzakciókat milyen mértékben kell elkülöníteni az egyidejű műveletek által végrehajtott módosításoktól. Az Azure Databricks írási ütközései az elkülönítési szinttől függenek.

A Delta Lake ACID-tranzakciós garanciákat biztosít az olvasásokban és írásokban. Ez azt jelenti, hogy:

  • Több író több fürtből egymás mellett módosíthat egy táblapartíciót. Az írók a táblázat konzisztens pillanatkép-nézetét látják, és az írások soros sorrendben történnek.
    • Az olvasók továbbra is egységes pillanatkép-nézetet láthatnak arról a tábláról, amellyel az Azure Databricks-feladat elindult, még akkor is, ha egy tábla módosul egy feladat során.

Tekintse meg az Azure Databricks acid-garanciáit.

Feljegyzés

Az Azure Databricks alapértelmezés szerint az összes táblához használja a Delta Lake-t. Ez a cikk a Delta Lake viselkedését ismerteti az Azure Databricksben.

Fontos

A metaadatok változásai miatt az egyidejű írási műveletek meghiúsulnak. Ezek a műveletek közé tartozik a táblaprotokoll, a táblatulajdonságok vagy az adatséma módosítása.

A streamelési olvasások meghiúsulnak, ha olyan véglegesítést tapasztalnak, amely módosítja a tábla metaadatait. Ha azt szeretné, hogy a stream folytatódjon, újra kell indítania. Az ajánlott módszerekért tekintse meg a strukturált streamelés éles környezettel kapcsolatos szempontjait.

Az alábbi példák a metaadatokat módosító lekérdezésekre mutatnak be példákat:

-- Set a table property.
ALTER TABLE table-name SET TBLPROPERTIES ('delta.isolationLevel' = 'Serializable')

-- Enable a feature using a table property and update the table protocol.
ALTER TABLE table_name SET TBLPROPERTIES ('delta.enableDeletionVectors' = true);

-- Drop a table feature.
ALTER TABLE table_name DROP FEATURE deletionVectors;

-- Upgrade to UniForm.
REORG TABLE table_name APPLY (UPGRADE UNIFORM(ICEBERG_COMPAT_VERSION=2));

-- Update the table schema.
ALTER TABLE table_name ADD COLUMNS (col_name STRING);

Írási ütközések sorszintű egyidejűséggel

A sorszintű egyidejűség csökkenti az egyidejű írási műveletek közötti ütközéseket azáltal, hogy észleli a sorszintű változásokat, és automatikusan feloldja azokat az ütközéseket, amelyek akkor fordulnak elő, amikor az egyidejű írások ugyanazon adatfájl különböző sorait frissítik vagy törlik.

A sorszintű egyidejűség általánosan elérhető a Databricks Runtime 14.2-es és újabb verziókban. A sorszintű egyidejűség alapértelmezés szerint a következő feltételek esetén támogatott:

  • A törlési vektorokkal rendelkező táblák engedélyezve és particionálás nélkül.
  • Folyékony fürtözésű táblák, kivéve, ha letiltotta a törlési vektorokat.

A partíciókat tartalmazó táblák nem támogatják a sorszintű egyidejűséget, de a törlési vektorok engedélyezésekor továbbra is elkerülhetik a OPTIMIZE és az összes többi írási művelet közötti ütközést. Lásd a sorszintű egyidejűség korlátozásait.

Más Databricks Runtime-verziók esetén lásd a sorszintű egyidejűség előnézetének viselkedését (örökölt).

MERGE INTO A sorszintű egyidejűség támogatásához a Photon szükséges a Databricks Runtime 14.2-ben. A Databricks Runtime 14.3 LTS-ben és újabb verziókban a Photon nem szükséges.

Az alábbi táblázat azt ismerteti, hogy az egyes izolációs szintek esetén, amikor sorszintű párhuzamosság engedélyezett, mely írási műveletek okozhatnak ütközéseket.

Feljegyzés

Az identitásoszlopokat tartalmazó táblák nem támogatják az egyidejű tranzakciókat. Lásd: Az identitásoszlopok használata a Delta Lake esetében.

INSERT (1) UPDATE, DELETE, MERGE INTO OPTIMIZE
INSERT Nem lehet ütközést
UPDATE, DELETE, MERGE INTO A WriteSerializable nem ütközhet. Ütközhet a szerializálhatóban ugyanazon sor módosításakor. Lásd a sorszintű egyidejűség korlátozásait. Ütközhet ugyanazon sor módosításakor. Lásd a sorszintű egyidejűség korlátozásait.
OPTIMIZE Nem lehet ütközést Ütközést okozhat a használat során ZORDER BY . Másként nem ütközhet. Ütközést okozhat a használat során ZORDER BY . Másként nem ütközhet.

Fontos

(1) A fenti táblák összes INSERT művelete olyan hozzáfűző műveleteket ír le, amelyek a véglegesítés előtt nem olvasnak adatokat ugyanabból a táblából. INSERT olyan műveletek, amelyek ugyanazt a táblát olvasó részlekérdezéseket tartalmaznak, ugyanazt az egyidejűséget támogatják, mint MERGE.

REORG a műveletek elkülönítési szemantikája megegyezik az OPTIMIZE adatfájlok újraírásakor a törlési vektorokban rögzített változásoknak megfelelően. Ha a REORG használatával alkalmazza a frissítést, a táblaprotokollok megváltoznak, ami ütközik az összes folyamatban lévő művelettel.

Ütközések írása sorszintű egyidejűség nélkül

Az alábbi táblázat azt ismerteti, hogy mely írási műveletek párjai ütközhetnek az egyes elkülönítési szinteken.

A táblák nem támogatják a sorszintű egyidejűséget, ha partíciók vannak definiálva, vagy nincsenek engedélyezve a törlési vektorok. A Databricks Runtime 14.2-es vagy újabb verziója szükséges a sorszintű egyidejűséghez.

Feljegyzés

Az identitásoszlopokat tartalmazó táblák nem támogatják az egyidejű tranzakciókat. Lásd: Identitásoszlopok használata a Delta Lake.

INSERT (1) UPDATE, DELETE, MERGE INTO OPTIMIZE
INSERT Nem lehet ütközést
UPDATE, DELETE, MERGE INTO A WriteSerializable nem ütközhet. Ütközhet a Szerializálható fájlban. Tekintse meg a partíciókkal való ütközések elkerülését. Ütközhet a Szerializálható és a WriteSerializable fájlban. Tekintse meg a partíciókkal való ütközések elkerülését.
OPTIMIZE Nem lehet ütközést Nem ütközhet olyan táblákban, amelyekben engedélyezve van a törlési vektor, kivéve, ha ZORDER BY van használatban. Máskülönben ütközhet. Nem ütközhet olyan táblákban, amelyekben engedélyezve van a törlési vektor, kivéve, ha ZORDER BY van használatban. Máskülönben ütközhet.

Fontos

(1) A fenti táblák összes INSERT művelete olyan hozzáfűző műveleteket ír le, amelyek a véglegesítés előtt nem olvasnak adatokat ugyanabból a táblából. INSERT olyan műveletek, amelyek ugyanazt a táblát olvasó részlekérdezéseket tartalmaznak, ugyanazt az egyidejűséget támogatják, mint MERGE.

REORG a műveletek elkülönítési szemantikája megegyezik az OPTIMIZE adatfájlok újraírásakor a törlési vektorokban rögzített változásoknak megfelelően. Ha a REORG használatával alkalmazza a frissítést, a táblaprotokollok megváltoznak, ami ütközik az összes folyamatban lévő művelettel.

A sorszintű egyidejűség korlátozásai

Bizonyos korlátozások a sorszintű egyidejűségre vonatkoznak. Az alábbi műveletek esetében az ütközések feloldása az Azure Databricksen történő írási ütközések normál egyidejűségét követi. Lásd: Írási ütközések sorszintű egyidejűség nélkül.

  • Összetett feltételes záradékokkal rendelkező parancsok, beleértve a következőket:
    • Összetett adattípusok, például szerkezetek, tömbök vagy térképek feltételei.
    • Nem determinisztikus kifejezéseket és al lekérdezéseket használó feltételek.
    • Korrelált alkonyatokat tartalmazó feltételek.
  • A Databricks Runtime 14.2-ben MERGE parancsoknak explicit predikátumot kell használniuk a céltáblán a forrástáblának megfelelő sorok szűréséhez. Az egyesítés feloldása érdekében a szűrő csak olyan sorokat vizsgál, amelyek ütközhetnek az egyidejű műveletek szűrőfeltételei alapján.

Feljegyzés

A sorszintű ütközésészlelés növelheti a teljes végrehajtási időt. Számos egyidejű tranzakció esetén az író rangsorolja a késést az ütközések feloldása és ütközések esetén.

A törlési vektorokra vonatkozó korlátozások is érvényesek. Lásd: Korlátozások.

Mikor véglegesíti a Delta Lake a táblázat olvasása nélkül?

A Delta Lake INSERT vagy hozzáfűzési műveletek nem olvassák be a tábla állapotát a véglegesítés előtt, ha a következő feltételek teljesülnek:

  1. A logikát SQL-logika vagy hozzáfűzési mód használatával INSERT fejezzük ki.
  2. A logika nem tartalmaz olyan al lekérdezéseket vagy feltételes elemeket, amelyek hivatkoznak az írási művelet által megcélzott táblára.

Más műveletekhez hasonlóan a Delta Lake a tranzakciónapló metaadataival ellenőrzi és megoldja a tábla verzióit a művelet során, de a tábla egyetlen verziója sincs ténylegesen beolvasva.

Feljegyzés

Számos gyakori minta MERGE műveleteket használ az adatok táblázatfeltételek alapján történő beszúrásához. Bár lehetséges lehet újraírni ezt a logikát INSERT utasítások használatával, ha bármely feltételes kifejezés a céltábla egyik oszlopára hivatkozik, ezek az utasítások ugyanolyan egyidejűségi korlátozásokkal rendelkeznek, mint MERGE.

Szerializálható és szerializálható elkülönítési szintek írása

A tábla elkülönítési szintje határozza meg, hogy a tranzakciókat milyen mértékben kell elkülöníteni az egyidejű tranzakciók által végrehajtott módosításoktól. Az Azure Databricks Delta Lake két elkülönítési szintet támogat: szerializálható és WriteSerializable.

  • Szerializálható: A legerősebb elkülönítési szint. Biztosítja, hogy a véglegesített írási műveletek és az összes olvasás szerializálható legyen. A műveletek akkor engedélyezettek, ha létezik olyan sorozat, amely egyenként hajtja végre őket, és ugyanazt az eredményt hozza létre, mint a táblában. Az írási műveletek esetében a sorozatszám pontosan megegyezik a táblázat előzményeiben látottakéval.

  • WriteSerializable (Alapértelmezett): A szerializálhatónál gyengébb elkülönítési szint. Csak azt biztosítja, hogy az írási műveletek (vagyis nem az olvasások) szerializálhatók legyenek. Ez azonban még mindig erősebb, mint a Pillanatkép elkülönítése. A WriteSerializable az alapértelmezett elkülönítési szint, mivel nagy adatkonzisztenciát és rendelkezésre állást biztosít a leggyakoribb műveletekhez.

    Ebben a módban a Delta-tábla tartalma eltérhet a táblaelőzményekben látható műveletek sorozatától. Ennek az az oka, hogy ez a mód lehetővé teszi bizonyos párhuzamos írási párok (például az X és az Y műveletek) folytatását, hogy az eredmény olyan legyen, mintha az Y-t X előtt hajtották volna végre (vagyis szerializálható közöttük), annak ellenére, hogy az előzmények azt mutatják, hogy az Y véglegesítése az X után történt. Az átrendezés letiltásához állítsa be a táblaelkülönítési szintet, szerializálható legyen, hogy a tranzakciók meghiúsuljanak.

Az olvasási műveletek mindig pillanatkép-elkülönítést használnak. Az íráselkülönítési szint határozza meg, hogy az olvasó láthat-e egy táblázat pillanatképét, amely az előzmények szerint "soha nem létezett".

A Szerializálható szint esetében az olvasó mindig csak az előzményeknek megfelelő táblákat látja. A WriteSerializable szint esetében az olvasó olyan táblát láthat, amely nem létezik a Delta-naplóban.

Vegyük például a txn1-et, egy hosszú ideig futó törlést és txn2-t, amely a txn1 által törölt adatokat szúrja be. txn2 és txn1 kész, és az előzményekben ebben a sorrendben vannak rögzítve. Az előzmények szerint a txn2-be beszúrt adatok nem létezhetnek a táblában. Szerializálható szint esetén az olvasó soha nem látja a txn2 által beszúrt adatokat. A WriteSerializable szint esetében azonban az olvasó egy bizonyos ponton láthatta a txn2 által beszúrt adatokat.

További információ arról, hogy az egyes elkülönítési szinteken milyen típusú műveletek ütközhetnek egymással, valamint a lehetséges hibákról lásd : Ütközések elkerülése particionálás és különálló parancsfeltételek használatával.

Az elkülönítési szint beállítása

Az elkülönítési szintet a ALTER TABLE paranccsal állíthatja be.

ALTER TABLE <table-name> SET TBLPROPERTIES ('delta.isolationLevel' = <level-name>)

ahol <level-name> a Serializable vagy a WriteSerializable.

Ha például az elkülönítési szintet alapértelmezettről az alapértelmezettre WriteSerializable szeretné módosítani, futtassa a következőt Serializable:

ALTER TABLE <table-name> SET TBLPROPERTIES ('delta.isolationLevel' = 'Serializable')

Az ütközések elkerülése particionálással és a parancsfeltételek szétválasztásával

A "can conflict" (Ütközés lehet) jelölésű összes esetben attól függ, hogy a két művelet ütközik-e, attól függ, hogy ugyanazon a fájlkészleten működnek-e. A két fájlhalmazt úgy lehet különállóvá tenni, hogy a táblát a műveletek feltételeiben használt oszlopokkal azonos oszlopokkal particionálja. A két parancs például UPDATE table WHERE date > '2010-01-01' ... és DELETE table WHERE date < '2010-01-01' ütközik, ha a tábla nincs dátum szerint particionálva, mivel mindkettő megpróbálhatja módosítani ugyanazt a fájlkészletet. A tábla date általi particionálása elkerüli az ütközést. Ezért a parancsban gyakran használt feltételeknek megfelelő táblák particionálása jelentősen csökkentheti az ütközéseket. A táblák magas számosságú oszlop szerinti particionálása azonban a nagy számú alkönyvtár miatt más teljesítményproblémákhoz vezethet.

Ütközési kivételek

Ha a tranzakciók ütköznek, a következő kivételek egyikét fogja látni:

ConcurrentAppendException

Ez a kivétel akkor fordul elő, ha egy egyidejű művelet fájlokat ad hozzá ugyanabban a partícióban (vagy egy nem particionált táblában bárhol), amelyet a művelet olvas. A fájl hozzáadását okozhatja INSERTa , DELETE, UPDATEvagy MERGE a műveletek.

A WriteSerializablealapértelmezett elkülönítési esetén a vakINSERT műveletek által hozzáadott fájlok (vagyis az adatok olvasása nélkül vakon hozzáfűző műveletek) nem ütköznek semmilyen művelettel, még akkor sem, ha ugyanahhoz a partícióhoz (vagy egy nem particionált táblához) érnek. Ha az elkülönítési szint Serializableértékre van állítva, akkor a vak hozzáfűzők ütközhetnek.

Ez a kivétel gyakran egyidejű DELETE, UPDATEvagy MERGE műveletek során jelentkezik. Bár az egyidejű műveletek fizikailag különböző partíciókönyvtárakat frissíthetnek, az egyik elolvashatja ugyanazt a partíciót, amelyet a másik egyidejűleg frissít, ami ütközést okoz. Ezt úgy kerülheti el, ha explicit módon határozza meg az elkülönítést a műveleti feltételben. Gondolja át a következő példát.

// 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()

Tegyük fel, hogy a fenti kódot párhuzamosan futtatja különböző dátumok vagy országok esetében. Mivel minden feladat egy független partíción dolgozik a cél Delta-táblán, nem várhatóak ütközések. A feltétel azonban nem elég explicit, és a teljes táblát átvizsgálhatja, és ütközhet a többi partíció egyidejű frissítésével. Ehelyett átírhatja az utasítást, konkrét dátumot és országot hozzáadva az egyesítési feltételhez az alábbi példában látható módon.

// 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()

Ez a művelet mostantól biztonságosan futtatható párhuzamosan különböző napokon és országokban.

ConcurrentDeleteReadException

Ez a kivétel akkor fordul elő, ha egy egyidejű művelet törölt egy fájlt, amelyet a művelet beolvasott. A gyakori okok a DELETEfájlok átírására irányuló műveletekUPDATEMERGE.

ConcurrentDeleteDeleteException

Ez a kivétel akkor fordul elő, ha egy egyidejű művelet törölt egy fájlt, amelyet a művelet is töröl. Ezt az okozhatja, hogy két párhuzamos tömörítési művelet ugyanazokat a fájlokat írja át.

MetadataChangedException

Ez a kivétel akkor fordul elő, ha egy egyidejű tranzakció frissíti egy Delta-tábla metaadatait. A gyakori okok a ALTER TABLE műveletek vagy a deltatáblába írt írások, amelyek frissítik a tábla sémáját.

ConcurrentTransactionException

Ha egy azonos ellenőrzőpont-helyet használó streamlekérdezés egyszerre többször is elindul, és egyszerre próbál meg írni a Delta táblába. Soha engedje, hogy két streamelési lekérdezés ugyanazt az ellenőrzőponthelyet használja, és egyszerre fusson.

ProtocolChangedException

Ez a kivétel a következő esetekben fordulhat elő:

  • Amikor a Delta-tábla új protokollverzióra frissül. A jövőbeli műveletek sikerességéhez szükség lehet a Databricks-futtatókörnyezet frissítésére.
  • Ha egyszerre több író is létrehoz vagy cserél egy táblát.
  • Ha egyszerre több író ír üres elérési útra.

További információ: Hogyan kezeli az Azure Databricks a Delta Lake szolgáltatáskompatibilitását?

Sorszintű egyidejűség előnézetének viselkedése (örökölt)

Ez a szakasz a Databricks Runtime 14.1-es és újabb verziójában a sorszintű egyidejűség előnézeti viselkedését ismerteti. A sorszintű egyidejűség mindig törlési vektorokat igényel.

A Databricks Runtime 13.3 LTS és újabb verziókban a "liquid clustering"-et engedélyező táblák automatikusan lehetővé teszik a sorszintű párhuzamosságot.

A Databricks Runtime 14.0-s és 14.1-es verziójában engedélyezheti a sorszintű egyidejűséget a törlési vektorokkal rendelkező táblák esetében a fürt vagy a SparkSession következő konfigurációjának beállításával:

spark.databricks.delta.rowLevelConcurrencyPreview = true

A Databricks Runtime 14.1-es és újabb verzióban a nem Foton-számítás csak a sorszintű egyidejűséget támogatja a műveletekhez DELETE .