Kompatibilita verzí prostředí

Important

Verze prostředí pro deklarativní kanály Sparku Lakeflow (SDP) jsou v beta verzi.

Kanály s verzí environment spouští Python kód prostřednictvím Spark Connect. Tato stránka popisuje, co je nekompatibilní, co se chová jinak, jak zkontrolovat ovlivněné vzory a jak migrovat existující kanál.

Omezení

Verze prostředí ještě nejsou kompatibilní se všemi funkcemi kanálu. Spuštění kanálu se sadou verzí prostředí selže, pokud kód kanálu Python provede některou z následujících věcí:

  • Ztlumí stav relace Sparku uvnitř funkce zdobené dekorátorem kanálů. Mezi příklady patří spark.conf.set(...), spark.sql("USE CATALOG ...")a createOrReplaceTempView.
  • Používá rozhraní PySpark API, která nejsou ve Spark Connect k dispozici, včetně SparkContextRDDSQLContext, a všech rozhraní API Py4J. Podívejte se, co je podporováno ve Spark Connectu.

Pokud povolení verze prostředí v kanálu způsobí selhání, zakázání verze prostředí vrátí kanál do předchozího stavu.

Změny chování

Spark Connect má malý počet rozdílů v chování oproti klasickému modulu runtime PySpark. Úplný odkaz najdete v tématu Spark Connect vs. Classic Spark . Kontrola kompatibility tyto vzory detekuje předem a blokuje povolení, dokud nebudou vyřešeny, takže je můžete najít a opravit předtím, než ovlivní produkční data.

V kanálu se nejběžnější situace, kdy se chování může lišit, jsou:

Prokládání konstrukce datového rámce a mutaci relací

Když kanál vytvoří datový rámec, ztlumí se stav relace Sparku (například změní výchozí katalog nebo schéma, nastaví konfiguraci, nahradí dočasné zobrazení nebo znovu zaregistruje UDF), pak použije datový rámec:

  • Bez verze prostředí datový rámec používá stav relace před mutací .
  • U verze prostředí datový rámec používá stav relace po mutaci .

Příklad:

from pyspark import pipelines as dp

spark.createDataFrame([(1, "Original Row")], ["id", "data"]) \
  .createOrReplaceTempView("my_view")

df = spark.sql("SELECT * FROM my_view")

spark.createDataFrame([(2, "Replaced Row")], ["id", "data"]) \
  .createOrReplaceTempView("my_view")

@dp.materialized_view
def mytable():
  return df

Bez verze mytable prostředí obsahuje [(1, "Original Row")]. S verzí mytable prostředí obsahuje [(2, "Replaced Row")].

UDF, které odkazují na proměnlivý stav Python

Když funkce definovaná uživatelem odkazuje na globální proměnnou Python, jejíž hodnota se po definování definovaného uživatelem změní:

  • Bez verze prostředí používá funkce definovaná uživatelem nejnovější hodnotu proměnné.
  • U verze prostředí používá funkce definovaná uživatelem hodnotu v okamžiku, kdy byla definovaná funkce definovaná uživatelem.

Příklad:

from pyspark import pipelines as dp
from pyspark.sql.functions import col, udf

suffix = "a"

@udf
def my_udf(s):
  return s + suffix

suffix = "b"

@dp.materialized_view
def my_mv():
  return spark.createDataFrame([("alex",)], ["name"]).select(my_udf(col("name")))

Bez verze my_mv prostředí obsahuje [("alex_b",)]. S verzí my_mv prostředí obsahuje [("alex_a",)].

Pokud kanál spoléhá na některý ze vzorů, před povolením verze prostředí ho auditujte.

Kontrola kompatibility

Kontrola kompatibility vám pomůže najít vzory kódu v kanálu, které by před povolením vytvořily různé výsledky ve verzi prostředí. Kontrola je opt-in. Pokud je kontrola povolená v kanálu:

  • Každé spuštění kanálu generuje jednu BehaviorChangeInSparkConnectWARN událost v protokolu událostí kanálu podle zjištěného vzoru.
  • V kanálu nelze povolit verzi prostředí, dokud nebudete řešit všechna upozornění kompatibility z předchozí úspěšné aktualizace.

Pokud kontrola není povolená, nevygenerují se žádné události a environment_version povolení není blokováno. Databricks doporučuje povolit kontrolu a přeložit všechny zjištěné vzory před povolením verze prostředí v kanálu.

Povolení kontroly v kanálu

Kontrolu kompatibility můžete povolit přidáním pipelines.environmentVersion.enableCompatibilityScan konfigurace kanálu. Konfiguraci můžete přidat prostřednictvím uživatelského rozhraní editoru kanálů nebo přidáním položky do kódu JSON konfigurace kanálu.

Prostřednictvím uživatelského rozhraní:

  1. V editoru kanálů klikněte na Nastavení.
  2. V nastavení kanálu vyhledejte část Konfigurace .
  3. Klikněte na ikonu Plus.Přidejte konfiguraci.
  4. Zadejte pipelines.environmentVersion.enableCompatibilityScan jako klíč a true jako hodnotu.
  5. Uložte nastavení kanálu.

V kódu JSON kanálu:

Do bloku přidejte následující položku configuration :

"configuration": {
  "pipelines.environmentVersion.enableCompatibilityScan": "true"
}
  1. Povolte kontrolu kanálu.
  2. Spusťte běh pipeline.
  3. Zadejte dotaz na protokol událostí kanálu pro BehaviorChangeInSparkConnectWARN události. Úplný seznam kódů problémů, vzorů příkladů a navrhovaných oprav najdete v referenčních informacích k událostem kompatibility .
  4. Aktualizujte kód kanálu tak, aby odebral zjištěné vzory a znovu spustil kanál, dokud se nevygenerují žádné další události.
  5. Přidejte environment_version do kanálu některou z metod v části Povolit verzi prostředí v kanálu.

Pokud se domníváte, že upozornění na kompatibilitu je falešně pozitivní a chcete přesto povolit environment_version , odeberte pipelines.environmentVersion.enableCompatibilityScan položku z konfigurace kanálu, aby se kontrola vynechala. (Nastavení hodnoty na false hodnotu není povoleno – položku musíte úplně odebrat.)

Předběžná kontrola se nespustí v kanálech, které nemají žádnou předchozí aktualizaci nebo kanály, které už mají sadu verzí prostředí.

Migrace existujícího kanálu do verzí prostředí

Pokud chcete migrovat existující kanál, který ještě nepoužívá verzi prostředí, postupujte podle tohoto kompletního pracovního postupu. Provede vás hledáním vzorů kódu, které se můžou chovat jinak v rámci Spark Connectu, opravují je a zavedou verzi prostředí bezpečně.

  1. Povolte kontrolu kompatibility v kanálu. Povolte kontrolu v kanálu, jak je popsáno v kontrole kompatibility. To způsobuje, že zjištěné vzory se zobrazí v protokolu událostí a co umožňuje předběžnou kontrolu, která chrání váš pokus o povolení.

  2. Aktivujte spuštění kanálu a zkontrolujte události kompatibility. Aktivují normální aktualizaci kanálu. Po úspěšném dokončení odešlete dotaz na protokol událostí kanálu na BehaviorChangeInSparkConnectWARN události. Každá událost hlásí jeden zjištěný vzor. Úplný seznam kódů problémů, vzorů příkladů a navrhovaných oprav najdete v referenčních informacích k událostem kompatibility .

  3. Aktualizujte kód kanálu tak, aby řešil zjištěné vzory. Pro každý zjištěný vzor aktualizujte kód kanálu podle navrhované opravy. Po každé změně aktivujte jinou aktualizaci kanálu a ověřte, že se už odpovídající události nezobrazí. Opakujte, dokud protokol událostí už nevrší žádné události kompatibility pro úspěšnou aktualizaci.

  4. Povolte verzi prostředí v kanálu. Po nejnovější úspěšné aktualizaci se žádné události kompatibility nepřidají environment_version do kanálu pomocí uživatelského rozhraní, rozhraní API nebo sady, jak je popsáno v části Povolení verze prostředí v kanálu. Další aktualizace se spustí se Spark Connect a připnutou jazykovou verzí Python a předinstalovanými knihovnami.

    Pokud aktualizace selže, protože upozornění kompatibility stále existují, vraťte environment_versionse ke kroku 2 a před dalším pokusem vyřešte zbývající upozornění.

  5. Ověřte migraci. Po dokončení první aktualizace verze prostředí ověřte:

    • Událost create_update v protokolu událostí zobrazuje environment_version nastavenou očekávanou hodnotu.
    • Kanál vytvoří očekávaná data a nezobrazí se žádné nové chybové události.
    • Přímé kontroly podřízených tabulek neobsahují žádné drobné rozdíly chování popsané ve změnách chování.

Vrácení zpět

Pokud se kanál po migraci chová nesprávně, odeberte ho environment_version z nastavení kanálu. Další aktualizace se spustí s předchozí konfigurací modulu runtime Python. Pomocí vráceného spuštění proveďte ladění a potom opakujte migraci z kroku 2 po identifikaci a vyřešení problému.

Referenční informace k událostem kompatibility

Pokud je v kanálu povolená kontrola kompatibility, protokol SDP vygeneruje jednu BehaviorChangeInSparkConnectWARN událost v protokolu událostí kanálu podle zjištěného vzoru. Pokud je kontrola povolená a předchozí úspěšná aktualizace zjistila všechny vzory, protokol SDP také blokuje environment_version povolení, dokud se tyto vzory nevyřeší.

Každá událost hlásí jeden kód problému, který identifikuje zjištěné informace. Pokud chcete vyhledat kód, najděte ho v tabulce Kódy problému – každý řádek odkazuje na oddíl kategorie, který obsahuje ukázkový vzor a navrhované opravy.

Obrazec události

BehaviorChangeInSparkConnect události se řídí standardním schématem protokolu událostí kanálu:

  • event_type je behavior_change_in_spark_connect.
  • level je WARN.
  • details behavior_change_in_spark_connect obsahuje objekt, který má jedno issue pole. Hodnota problému je jedním z níže uvedených kódů.
  • message je čitelný popis zjištěného vzoru.

Kódy problémů

Kategorie Kód problému Description
Databáze a katalogové mutaci USE_CATALOG_OUTSIDE_QUERY_FUNCTION_AFTER_DATAFRAME_COULD_CHANGE_BEHAVIOR Výchozí katalog se po vytvoření datového rámce změnil. Existující datový rámec může přeložit tabulky pomocí nového výchozího katalogu.
Databáze a katalogové mutaci USE_CATALOG_OUTSIDE_QUERY_FUNCTION_COULD_CHANGE_BEHAVIOR USE CATALOG byl volán mimo funkci zdobenou dekorátorem kanálů. Výchozí katalog se může neočekávaně změnit pro následné operace.
Databáze a katalogové mutaci USE_DATABASE_OUTSIDE_QUERY_FUNCTION_AFTER_DATAFRAME_COULD_CHANGE_BEHAVIOR Výchozí databáze se po vytvoření datového rámce změnila. Existující datový rámec může přeložit tabulky pomocí nové výchozí databáze.
Databáze a katalogové mutaci USE_DATABASE_OUTSIDE_QUERY_FUNCTION_COULD_CHANGE_BEHAVIOR USE DATABASE byl volán mimo funkci zdobenou dekorátorem kanálů. Výchozí databáze se může neočekávaně změnit pro následné operace.
Dychtivé provádění ve funkcích toku CHECKPOINT_COMMAND_WITHIN_QUERY_FUNCTION_NOT_SUPPORTED Funkce toku volá příkaz kontrolního bodu.
Dychtivé provádění ve funkcích toku CREATE_DATAFRAME_VIEW_WITHIN_QUERY_FUNCTION_NOT_SUPPORTED Funkce toku dychtivě vytvoří zobrazení datového rámce (createOrReplaceTempView nebo podobné).
Dychtivé provádění ve funkcích toku CREATE_RESOURCE_PROFILE_COMMAND_WITHIN_QUERY_FUNCTION_NOT_SUPPORTED Funkce toku vytvoří profil prostředku.
Dychtivé provádění ve funkcích toku GET_RESOURCES_COMMAND_WITHIN_QUERY_FUNCTION_NOT_SUPPORTED Funkce toku volá spark.resources nebo související rozhraní API prostředků.
Dychtivé provádění ve funkcích toku MERGE_INTO_TABLE_COMMAND_WITHIN_QUERY_FUNCTION_NOT_SUPPORTED Funkce toku provádí s cílovou tabulkou dychtivou činnost MERGE INTO .
Dychtivé provádění ve funkcích toku ML_COMMAND_WITHIN_QUERY_FUNCTION_NOT_SUPPORTED Funkce toku provádí dychtivou operaci Spark ML.
Dychtivé provádění ve funkcích toku REGISTER_DATA_SOURCE_WITHIN_QUERY_FUNCTION_NOT_SUPPORTED Funkce toku zaregistruje Python zdroj dat.
Dychtivé provádění ve funkcích toku STREAMING_QUERY_COMMAND_WITHIN_QUERY_FUNCTION_NOT_SUPPORTED Funkce toku pracuje s aktivním popisovačem dotazu streamování.
Dychtivé provádění ve funkcích toku STREAMING_QUERY_LISTENER_BUS_COMMAND_WITHIN_QUERY_FUNCTION_NOT_SUPPORTED Funkce toku zaregistruje nebo odebere naslouchací proces dotazu streamování.
Dychtivé provádění ve funkcích toku STREAMING_QUERY_MANAGER_COMMAND_WITHIN_QUERY_FUNCTION_NOT_SUPPORTED Volání funkce spark.streams toku pro správu streamovaných dotazů.
Dychtivé provádění ve funkcích toku WRITE_OPERATION_V2_WITHIN_QUERY_FUNCTION_NOT_SUPPORTED Funkce toku provádí dychtivou DataFrameWriterV2 operaci.
Dychtivé provádění ve funkcích toku WRITE_OPERATION_WITHIN_QUERY_FUNCTION_NOT_SUPPORTED Funkce toku provádí dychtivou DataFrame.write operaci.
Dychtivé provádění ve funkcích toku WRITE_STREAM_OPERATION_START_WITHIN_QUERY_FUNCTION_NOT_SUPPORTED Funkce toku spustí dotaz streamování (writeStream.start()).
Změny konfigurace Sparku CHANGE_CONF_INSIDE_QUERY_FUNCTION_NOT_SUPPORTED spark.conf.set() nebo spark.conf.unset() byl volán uvnitř funkce zdobené dekorátorem kanálů. Tato možnost není podporována ve verzi prostředí.
Změny konfigurace Sparku SET_CONF_AFTER_DATAFRAME_COULD_CHANGE_BEHAVIOR spark.conf.set() byl volán mimo funkci dekorátoru kanálů po vytvoření datového rámce. Změna konfigurace může mít vliv na existující datový rámec v době provádění.
Změny konfigurace Sparku UNSET_CONF_AFTER_DATAFRAME_COULD_CHANGE_BEHAVIOR spark.conf.unset() byl volán mimo funkci dekorátoru kanálů po vytvoření datového rámce. Změna konfigurace může mít vliv na existující datový rámec v době provádění.
Dočasné nahrazení zobrazení REPLACE_GLOBAL_TEMP_VIEW_AFTER_DATAFRAME_COULD_CHANGE_BEHAVIOR Globální dočasné zobrazení bylo nahrazeno po vytvoření datového rámce odkazujícího na něj. Nahrazení se může projevit v existujícím datovém rámci.
Dočasné nahrazení zobrazení REPLACE_TEMP_VIEW_AFTER_DATAFRAME_COULD_CHANGE_BEHAVIOR Dočasné zobrazení bylo nahrazeno po vytvoření datového rámce odkazujícího na něj. Nahrazení se může projevit v existujícím datovém rámci.
UDF a UDTF mutací OVERWRITE_SESSION_UDF_AFTER_DATAFRAME_COULD_CHANGE_BEHAVIOR Funkce definovaná uživatelem byla po vytvoření datového rámce znovu zaregistrována se stejným názvem. Existující datový rámec může použít novou definici definované uživatelem.
UDF a UDTF mutací OVERWRITE_SESSION_UDTF_AFTER_DATAFRAME_COULD_CHANGE_BEHAVIOR UDTF se po vytvoření datového rámce znovu zaregistroval se stejným názvem. Existující datový rámec může použít novou definici UDTF.
UDF a UDTF mutací UDF_REFERENCES_GLOBAL_VARIABLE_COULD_CHANGE_BEHAVIOR Funkce definovaná uživatelem odkazuje na globální proměnlivou proměnnou Python. U verze prostředí používá funkce definovaná uživatelem hodnotu proměnné v okamžiku, kdy byla definovaná funkce definovaná uživatelem, nikoli při vyvolání.
UDF a UDTF mutací UDTF_REFERENCES_GLOBAL_VARIABLE_COULD_CHANGE_BEHAVIOR UDTF odkazuje na globální proměnlivou proměnnou Python. U verze prostředí používá UDTF hodnotu proměnné v okamžiku, kdy byl definovaný UDTF, nikoli při vyvolání.

Databáze a katalogové mutaci

Tyto problémy se vygenerují, když kód kanálu ztlumí výchozí databázi nebo katalog. Ve verzi prostředí můžou datové rámce vytvořené před tím, než se mutací podařilo přeložit tabulky pomocí nové databáze nebo katalogu.

Příklad vzoru, který aktivuje událost:

from pyspark import pipelines as dp

spark.sql("USE CATALOG marketing")
df = spark.read.table("events")

spark.sql("USE CATALOG sales")  # changes the default catalog after df was created

@dp.materialized_view
def events_summary():
  return df.groupBy("region").count()

Bez verze prostředí se df přeloží events z marketing katalogu. S verzí prostředí se df přeloží events z sales katalogu.

Navrhovaná oprava: Plně opravňující názvy tabulek, takže překlad nezávisí na výchozím katalogu nebo databázi, a vyhněte se změně výchozího katalogu nebo databáze mezi vytvořením a použitím datového rámce.

from pyspark import pipelines as dp

df = spark.read.table("marketing.default.events")

@dp.materialized_view
def events_summary():
  return df.groupBy("region").count()

Změny konfigurace Sparku

Tyto problémy se vygenerují, když kód kanálu ztlumí konfiguraci Sparku způsobem, který může změnit chování datového rámce v rámci verze prostředí.

Příklad vzoru, který aktivuje událost:

from pyspark import pipelines as dp

df = spark.read.table("events")

spark.conf.set("spark.sql.ansi.enabled", "true")  # changes session conf after df was created

@dp.materialized_view
def events_strict():
  return df.selectExpr("CAST(price AS INT) AS price")

Bez verze prostředí používá přetypování hodnotu conf při vytváření datového rámce. Ve verzi prostředí se přetypování používá spark.sql.ansi.enabled=true a může selhat při neplatném vstupu.

Navrhovaná oprava: Před vytvořením datového rámce nastavte všechny požadované konfigurace Sparku v horní části souboru kanálu. Pro konfiguraci jednotlivých dotazů použijte nastavení kanálu configuration ve specifikaci kanálu.

Dočasné nahrazení zobrazení

Tyto problémy se vygenerují, když kód kanálu nahradí dočasné zobrazení po vytvoření datového rámce odkazujícího na něj. U verze prostředí může existující datový rámec odrážet nový obsah zobrazení.

Příklad vzoru, který aktivuje událost:

from pyspark import pipelines as dp

spark.createDataFrame([(1, "Original Row")], ["id", "data"]) \
  .createOrReplaceTempView("my_view")

df = spark.sql("SELECT * FROM my_view")

spark.createDataFrame([(2, "Replaced Row")], ["id", "data"]) \
  .createOrReplaceTempView("my_view")

@dp.materialized_view
def mytable():
  return df

Bez verze mytable prostředí obsahuje [(1, "Original Row")]. S verzí mytable prostředí obsahuje [(2, "Replaced Row")].

Navrhovaná oprava: Vytvořte každé dočasné zobrazení jednou a nenahrazovat ho. Pokud potřebujete více zobrazení se souvisejícími daty, zadejte každý jedinečný název.

UDF a UDTF mutací

Tyto problémy se vygenerují, když kód kanálu ztlumí UDF nebo UDTF způsoby, které mění chování v rámci verze prostředí.

Příklad vzoru, který aktivuje událost:

from pyspark import pipelines as dp
from pyspark.sql.functions import col, udf

suffix = "a"

@udf
def my_udf(s):
  return s + suffix

suffix = "b"

@dp.materialized_view
def my_mv():
  return spark.createDataFrame([("alex",)], ["name"]).select(my_udf(col("name")))

Bez verze my_mv prostředí obsahuje [("alex_b",)]. S verzí my_mv prostředí obsahuje [("alex_a",)].

Navrhované opravy: Předejte hodnoty do funkce definované uživatelem jako argumenty místo jejich zachytávání z globálních Python nebo nastavte globální před definováním funkce definovanou uživatelem a potom ho neztlumujte.

from pyspark import pipelines as dp
from pyspark.sql.functions import col, lit, udf

@udf
def append_suffix(s, suffix):
  return s + suffix

@dp.materialized_view
def my_mv():
  return spark.createDataFrame([("alex",)], ["name"]).select(append_suffix(col("name"), lit("b")))

Dychtivé provádění ve funkcích toku

Tyto problémy se vygenerují, když kód kanálu provádí dychtivý příkaz Sparku uvnitř funkce zdobené dekorátorem kanálů (@tableatd @materialized_view.). Očekává se, že funkce toku definují a vrací datový rámec; příkazy, které zapisují data, spravují streamované dotazy, registrují prostředky nebo spouští operace ML, nejsou povoleny uvnitř funkce toku se sadou verzí prostředí.

Navrhovaná oprava: Přesuňte dychtivou operaci mimo funkci toku a vraťte datový rámec z funkce toku. Vedlejší účinky, jako je zápis do tabulky nebo spuštění streamovacího dotazu, patří mimo definici kanálu; modul kanálu zpracovává materializaci datového rámce vráceného funkcí toku.

Vyhledání událostí kompatibility v protokolu událostí

Následující dotaz vrátí všechny události kompatibility kanálu seřazené jako poslední:

SELECT
  timestamp,
  message,
  details:behavior_change_in_spark_connect:issue AS issue
FROM event_log(<pipeline-id>)
WHERE event_type = 'behavior_change_in_spark_connect'
  AND level = 'WARN'
ORDER BY timestamp DESC;

Počet událostí podle kódu problému v nedávných aktualizacích:

SELECT
  details:behavior_change_in_spark_connect:issue AS issue,
  COUNT(*) AS occurrences
FROM event_log(<pipeline-id>)
WHERE event_type = 'behavior_change_in_spark_connect'
  AND level = 'WARN'
GROUP BY 1
ORDER BY occurrences DESC;

Informace o dotazování protokolu událostí najdete v tématu Dotazování protokolu událostí.

Dodatečné zdroje