Dykk ned i Delta Lake: Schema Enforcement and Evolution

Hei, Habr! Jeg presenterer for din oppmerksomhet en oversettelse av artikkelen "Diving Into Delta Lake: Schema Enforcement & Evolution" forfatterne Burak Yavuz, Brenner Heintz og Denny Lee, som ble utarbeidet i påvente av kursstart Dataingeniør fra OTUS.

Dykk ned i Delta Lake: Schema Enforcement and Evolution

Data, som vår erfaring, akkumuleres og utvikler seg konstant. For å følge med må våre mentale modeller av verden tilpasse seg nye data, hvorav noen inneholder nye dimensjoner – nye måter å observere ting vi ikke hadde noen anelse om før. Disse mentale modellene er ikke mye forskjellig fra tabellskjemaene som bestemmer hvordan vi kategoriserer og behandler ny informasjon.

Dette bringer oss til spørsmålet om skjemahåndtering. Ettersom forretningsutfordringer og krav endres over tid, endrer strukturen på dataene dine seg også. Delta Lake gjør det enkelt å introdusere nye målinger etter hvert som data endres. Brukere har tilgang til enkel semantikk for å administrere tabellskjemaene sine. Disse verktøyene inkluderer Schema Enforcement, som beskytter brukere mot utilsiktet å forurense tabellene deres med feil eller unødvendige data, og Schema Evolution, som lar nye kolonner med verdifulle data automatisk legges til de riktige stedene. I denne artikkelen skal vi dykke dypere inn i bruken av disse verktøyene.

Forstå tabellskjemaer

Hver DataFrame i Apache Spark inneholder et skjema som definerer formen til dataene, for eksempel datatyper, kolonner og metadata. Med Delta Lake lagres tabellskjemaet i JSON-format inne i transaksjonsloggen.

Hva er ordningshåndhevelse?

Schema Enforcement, også kjent som Schema Validation, er en sikkerhetsmekanisme i Delta Lake som sikrer datakvalitet ved å avvise poster som ikke samsvarer med tabellens skjema. I likhet med vertinnen i resepsjonen på en populær restaurant med kun reservasjoner, sjekker hun om hver kolonne med data som legges inn i tabellen er i den tilsvarende listen over forventede kolonner (med andre ord om det er en "reservasjon" for hver av dem ), og avviser alle poster med kolonner som ikke er på listen.

Hvordan fungerer skjemahåndhevelse?

Delta Lake bruker skjema-på-skriv-kontroll, som betyr at alle nye skrivinger til tabellen sjekkes for kompatibilitet med måltabellens skjema ved skrivetidspunkt. Hvis skjemaet er inkonsekvent, avbryter Delta Lake transaksjonen helt (ingen data skrives) og oppretter et unntak for å varsle brukeren om inkonsekvensen.
Delta Lake bruker følgende regler for å avgjøre om en post er kompatibel med en tabell. DataFrame som skal skrives:

  • kan ikke inneholde flere kolonner som ikke er i måltabellens skjema. Motsatt er alt i orden hvis de innkommende dataene ikke inneholder absolutt alle kolonnene fra tabellen - disse kolonnene vil ganske enkelt bli tildelt nullverdier.
  • kan ikke ha kolonnedatatyper som er forskjellige fra datatypene til kolonnene i måltabellen. Hvis måltabellkolonnen inneholder StringType-data, men den tilsvarende kolonnen i DataFrame inneholder IntegerType-data, vil skjemahåndhevelse gi et unntak og forhindre at skriveoperasjonen finner sted.
  • kan ikke inneholde kolonnenavn som bare avviker i store og små bokstaver. Dette betyr at du ikke kan ha kolonner som heter 'Foo' og 'foo' definert i samme tabell. Mens Spark kan brukes i modusen som skiller mellom store og små bokstaver eller som ikke skiller mellom store og små bokstaver (standard), er Delta Lake bevaring av store og små bokstaver, men er ufølsom i skjemalagringen. Parkett skiller mellom store og små bokstaver ved lagring og retur av kolonneinformasjon. For å unngå mulige feil, datakorrupsjon eller tap av data (noe vi personlig opplevde hos Databricks), bestemte vi oss for å legge til denne begrensningen.

For å illustrere dette, la oss ta en titt på hva som skjer i koden nedenfor når vi prøver å legge til noen nylig genererte kolonner til en Delta Lake-tabell som ennå ikke er konfigurert til å godta dem.

# Сгенерируем DataFrame ссуд, который мы добавим в нашу таблицу Delta Lake
loans = sql("""
            SELECT addr_state, CAST(rand(10)*count as bigint) AS count,
            CAST(rand(10) * 10000 * count AS double) AS amount
            FROM loan_by_state_delta
            """)

# Вывести исходную схему DataFrame
original_loans.printSchema()

root
  |-- addr_state: string (nullable = true)
  |-- count: integer (nullable = true)
 
# Вывести новую схему DataFrame
loans.printSchema()
 
root
  |-- addr_state: string (nullable = true)
  |-- count: integer (nullable = true)
  |-- amount: double (nullable = true) # new column
 
# Попытка добавить новый DataFrame (с новым столбцом) в существующую таблицу
loans.write.format("delta") 
           .mode("append") 
           .save(DELTALAKE_PATH)

Returns:

A schema mismatch detected when writing to the Delta table.
 
To enable schema migration, please set:
'.option("mergeSchema", "true")'
 
Table schema:
root
-- addr_state: string (nullable = true)
-- count: long (nullable = true)
 
Data schema:
root
-- addr_state: string (nullable = true)
-- count: long (nullable = true)
-- amount: double (nullable = true)
 
If Table ACLs are enabled, these options will be ignored. Please use the ALTER TABLE command for changing the schema.

I stedet for automatisk å legge til nye kolonner, påtvinger Delta Lake et skjema og slutter å skrive. For å finne ut hvilken kolonne (eller sett med kolonner) som forårsaker avviket, sender Spark ut begge skjemaene fra stabelsporingen for sammenligning.

Hva er fordelen med å håndheve et skjema?

Fordi skjemahåndhevelse er en ganske streng kontroll, er det et utmerket verktøy å bruke som en portvakt til et rent, fullstendig transformert datasett som er klart for produksjon eller forbruk. Vanligvis brukt på tabeller som direkte mater data:

  • Maskinlæringsalgoritmer
  • BI dashbord
  • Dataanalyse og visualiseringsverktøy
  • Ethvert produksjonssystem som krever svært strukturerte, sterkt typede semantiske skjemaer.

For å forberede dataene sine for dette siste hinderet, bruker mange brukere en enkel "multi-hop"-arkitektur som gradvis introduserer struktur i tabellene deres. For å lære mer om dette, kan du sjekke ut artikkelen Maskinlæring i produksjonsgrad med Delta Lake.

Selvfølgelig kan skjemahåndhevelse brukes hvor som helst i pipelinen din, men husk at streaming til en tabell i dette tilfellet kan være frustrerende fordi du for eksempel glemte at du la til en annen kolonne til de innkommende dataene.

Forhindrer datafortynning

Nå lurer du kanskje på, hva er alt oppstyret om? Tross alt, noen ganger kan en uventet "skjemamismatch"-feil snuble deg opp i arbeidsflyten din, spesielt hvis du er ny i Delta Lake. Hvorfor ikke bare la skjemaet endres etter behov, slik at jeg kan skrive DataFrame uansett hva?

Som det gamle ordtaket sier, "en unse av forebygging er verdt et pund av kur." På et tidspunkt, hvis du ikke passer på å håndheve skjemaet ditt, vil problemer med kompatibilitet med datatyper føre til stygge hoder – tilsynelatende homogene rådatakilder kan inneholde kantsaker, ødelagte kolonner, misformede tilordninger eller andre skumle ting å drømme om i mareritt. Den beste tilnærmingen er å stoppe disse fiendene ved porten – med skjemahåndhevelse – og håndtere dem i lyset, i stedet for senere når de begynner å lure i det mørke dypet av produksjonskoden din.

Håndheving av et skjema gir deg forsikringen om at tabellens skjema ikke endres med mindre du godkjenner endringen. Dette forhindrer datafortynning, som kan oppstå når nye kolonner legges til så ofte at tidligere verdifulle, komprimerte tabeller mister sin mening og nytte på grunn av dataoversvømmelse. Ved å oppmuntre deg til å være forsettlig, sette høye standarder og forvente høy kvalitet, gjør skjemahåndhevelse akkurat det den er designet for å gjøre – hjelper deg å holde deg samvittighetsfull og regnearkene dine rene.

Hvis du ved nærmere vurdering bestemmer deg for at du virkelig trenge legg til en ny kolonne - ikke noe problem, nedenfor er en enlinjefiks. Løsningen er utviklingen av kretsen!

Hva er skjemaevolusjon?

Skjemaevolusjon er en funksjon som lar brukere enkelt endre gjeldende tabellskjema i henhold til data som endres over tid. Det brukes oftest når du utfører en tilleggs- eller omskrivingsoperasjon for å automatisk tilpasse skjemaet til å inkludere en eller flere nye kolonner.

Hvordan fungerer skjemaevolusjon?

Etter eksemplet fra forrige seksjon kan utviklere enkelt bruke skjemaevolusjon for å legge til nye kolonner som tidligere ble avvist på grunn av skjemainkonsekvens. Kretsevolusjon aktiveres ved å legge til .option('mergeSchema', 'true') til Spark-teamet ditt .write или .writeStream.

# Добавьте параметр mergeSchema
loans.write.format("delta") 
           .option("mergeSchema", "true") 
           .mode("append") 
           .save(DELTALAKE_SILVER_PATH)

For å se grafen, kjør følgende Spark SQL-spørring

# Создайте график с новым столбцом, чтобы подтвердить, что запись прошла успешно
%sql
SELECT addr_state, sum(`amount`) AS amount
FROM loan_by_state_delta
GROUP BY addr_state
ORDER BY sum(`amount`)
DESC LIMIT 10

Dykk ned i Delta Lake: Schema Enforcement and Evolution
Alternativt kan du angi dette alternativet for hele Spark-økten ved å legge til spark.databricks.delta.schema.autoMerge = True til Spark-konfigurasjonen. Men bruk dette med forsiktighet, siden skjemahåndhevelse ikke lenger vil varsle deg om utilsiktede skjemainkonsekvenser.

Ved å inkludere parameteren i forespørselen mergeSchema, alle kolonner som er tilstede i DataFrame, men ikke i måltabellen, legges automatisk til på slutten av skjemaet som en del av en skrivetransaksjon. Nestede felt kan også legges til, og disse vil også bli lagt til på slutten av de tilsvarende strukturkolonnene.

Datoingeniører og dataforskere kan bruke dette alternativet til å legge til nye kolonner (kanskje en nylig sporet beregning eller denne månedens salgsytelseskolonne) til deres eksisterende maskinlæringsproduksjonstabeller uten å bryte eksisterende modeller basert på gamle kolonner.

Følgende typer skjemaendringer er tillatt som en del av skjemautviklingen under en tabelltilføyelse eller omskriving:

  • Legge til nye kolonner (dette er det vanligste scenariet)
  • Endre datatyper fra NullType -> enhver annen type eller promotering fra ByteType -> ShortType -> IntegerType

Andre endringer som ikke er tillatt innenfor skjemautvikling krever at skjemaet og dataene skrives om ved å legge til .option("overwriteSchema", "true"). For eksempel, i tilfellet der kolonnen "Foo" opprinnelig var et heltall og det nye skjemaet ville være en strengdatatype, må alle Parquet(data)-filer skrives om. Slike endringer inkluderer:

  • slette en kolonne
  • endre datatypen til en eksisterende kolonne (på plass)
  • gi nytt navn til kolonner som bare avviker i store og små bokstaver (for eksempel "Foo" og "foo")

Til slutt, med neste utgivelse av Spark 3.0, vil eksplisitt DDL støttes fullt ut (ved å bruke ALTER TABLE), slik at brukere kan utføre følgende handlinger på tabellskjemaer:

  • legge til kolonner
  • endre kolonnekommentarer
  • angi tabellegenskaper som styrer tabellens oppførsel, for eksempel å angi hvor lenge en transaksjonslogg skal lagres.

Hva er fordelen med kretsevolusjon?

Schema evolusjon kan brukes når du har tenkt endre skjemaet for tabellen (i motsetning til når du ved et uhell la til kolonner i DataFrame som ikke skulle være der). Dette er den enkleste måten å migrere skjemaet på fordi det automatisk legger til de riktige kolonnenavnene og datatypene uten å eksplisitt deklarere dem.

Konklusjon

Skjemahåndhevelse avviser alle nye kolonner eller andre skjemaendringer som ikke er kompatible med tabellen din. Ved å sette og opprettholde disse høye standardene kan analytikere og ingeniører stole på at dataene deres har det høyeste nivået av integritet, kommunisere det klart og tydelig, slik at de kan ta bedre forretningsbeslutninger.

På den annen side utfyller skjemaevolusjon håndhevelse ved å forenkle påstått automatiske skjemaendringer. Det burde tross alt ikke være vanskelig å legge til en kolonne.

Den tvungne anvendelsen av ordningen er yang, hvor utviklingen av ordningen er yin. Når de brukes sammen, gjør disse funksjonene støydemping og signalinnstilling enklere enn noen gang.

Vi vil også takke Mukul Murthy og Pranav Anand for deres bidrag til denne artikkelen.

Andre artikler i denne serien:

Dykk ned i Delta Lake: Pakker ut transaksjonsloggen

relaterte artikler

Maskinlæring i produksjonsgrad med Delta Lake

Hva er en datainnsjø?

Finn ut mer om kurset

Kilde: www.habr.com

Legg til en kommentar