The Role of Delta Lake: Schema Enforcement and Evolution

Përshëndetje, Habr! Po ju prezantoj një përkthim të artikullit «Immersing Into Delta Lake: Schema Enforcement & Evolution» by Burak Yavuz, Brenner Heintz, and Denny Lee, prepared ahead of the course launch Inxhinier i të Dhënave from OTUS.

The Role of Delta Lake: Schema Enforcement and Evolution

Data, like our experience, is constantly accumulating and evolving. To keep pace, our mental models of the world must adapt to new data, some of which contain new dimensions — new ways to observe things we previously had no idea about. These mental models are little different from table schemas that define how we classify and process new information.

This brings us to the question of schema management. As business tasks and requirements change over time, so does the structure of your data. Delta Lake allows new dimensions to be easily introduced as data changes. Users have access to simple semantics for managing the schemas of their tables. These tools include schema enforcement, which protects users from inadvertently cluttering their tables with mistakes or unnecessary data, and schema evolution, which allows the automatic addition of new columns with valuable data in appropriate places. In this article, we will delve into the use of these tools.

Understanding Table Schemas

Every DataFrame in Apache Spark has a schema that defines the form of the data, such as data types, columns, and metadata. With Delta Lake, the table schema is stored in JSON format within the transaction log.

What is Schema Enforcement?

Schema enforcement, also known as schema validation, is a protective mechanism in Delta Lake that ensures data quality by rejecting records that do not conform to the table schema. Much like a host at a restaurant who only accepts reservations, it checks if each data column being entered into the table is on the expected list of columns (in other words, if each has a 'reservation'), and rejects any records with columns not on the list.

How does schema enforcement work?

Delta Lake përdor verifikimin e skemës gjatë shkrimit, që do të thotë se të gjitha shkrimet e reja në tabelë verifikohen për përputhshmëri me skemën e tabelës së qëllimit gjatë shkrimit. Nëse skema nuk është e përputhshme, Delta Lake anulon plotësisht transaksionin (të dhënat nuk shkruhen) dhe krijon një përjashtim për të informuar përdoruesin mbi mos përputhshmërinë.
Për të përcaktuar përputhshmërinë e shkrimit me tabelën, Delta Lake përdor rregullat e mëposhtme. DataFrame që po shkruhet:

  • nuk mund të përmbajë kolona shtesë, të cilat nuk gjenden në skemën e tabelës së qëllimit. Anasjelltas, është në rregull nëse të dhënat e ardhura nuk përmbajnë të gjitha kolonat nga tabela – këtyre kolonave thjesht do t'u jepet një vlerë zero.
  • nuk mund të ketë tipe të dhënash të kolonave që diferencohen nga tipet e të dhënave të kolonave në tabelën e qëllimit. Nëse një kolonë në tabelën e qëllimit përmban të dhëna të tipit StringType, por kolona përkatëse në DataFrame përmban të dhëna të tipit IntegerType, imponimi i skemës do të shkaktojë një përjashtim dhe do të parandalojë ekzekutimin e operacionit të shkrimit.
  • nuk mund të përmbajë emra kolonash që ndryshojnë vetëm në rast. Kjo do të thotë se nuk mund të keni kolona me emra ‘Foo’ dhe ‘foo’ të përcaktuar në të njëjtën tabelë. Edhe pse Spark mund të përdoret në mënyrë të ndjeshme apo të pavëmendshme ndaj rastit (në mënyrë të parazgjedhur), Delta Lake ruan rastin, por është i pavëmendshëm në kuadër të ruajtjes së skemës. Parquet është i ndjeshëm ndaj rastit gjatë ruajtjes dhe rikthimit të informacionit të kolonës. Për të shmangur gabimet e mundshme, dëmtimin e të dhënave ose humbjen e tyre (me të cilat ne personalisht kemi hasur në Databricks), ne vendosëm të shtojmë këtë kufizim.

Për të ilustruar këtë, le të shohim se çfarë ndodh në kodin e mëposhtëm kur përpiqemi të shtojmë disa kolona të reja të gjeneruara në tabelën Delta Lake, e cila ende nuk është konfiguruar për t'i pranuar ato.

# Сгенерируем 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.

Në vend që të shtojë automatikisht kolonat e reja, Delta Lake imponon skemën dhe ndalon shkrimin. Për të ndihmuar në përcaktimin se cila kolonë (ose disa prej tyre) është shkaku i mos përputhshmërisë, Spark nxjerr të dy skemat nga stack trace për krahasim.

Cila është dobi e imponimit të skemës?

Pasi aplikimi i detyrueshëm i skemave paraqet një kontroll të mjaftueshëm të rreptë, ai është një mjet i shkëlqyer për t'u përdorur si një portier i një grupi të dhënash të pastër dhe të transformuar plotësisht, i gatshëm për prodhim ose konsum. Si rregull, aplikohet në tabela që drejtpërdrejt ofrojnë të dhëna:

  • Algoritmet e mësimit të makinerive
  • Panele BI
  • Analiza e të dhënave dhe mjetet e vizualizimit
  • Çdo sistem prodhimi që kërkon skema semantike shumë të strukturuara dhe shumë të tipizuara.

Për të përgatitur të dhënat tuaja për këtë barrierë përfundimtare, shumë përdorues përdorin një arkitekturë të thjeshtë “multi-hop”, e cila gradualisht sjell strukturë në tabelat e tyre. Për të mësuar më shumë rreth kësaj, mund të konsultoheni me artikullin Mësimi i makinave në nivelin e prodhimit me Delta Lake.

Sigurisht, aplikimi i detyrueshëm i skemave mund të përdoret kudo në pipelinën tuaj, por mbani mend se regjistrimi në rrjedhë në tabelë në këtë rast mund të jetë frustrues, për shkak se, për shembull, keni harruar se keni shtuar një kolonë të re në të dhënat hyrëse.

Parandalimi i hollimit të të dhënave

Në këtë pikë, mund të pyesni veten se çfarë është gjithë ky entuziazëm? Pas gjithë kësaj, ndonjëherë një gabim i papritur "mospërputhje skemash" mund t'ju vërë pengesa në procesin tuaj të punës, veçanërisht nëse jeni fillestar në Delta Lake. Pse thjesht të mos lejojmë skemën të ndryshojë siç është e nevojshme për të mundësuar shkrimin tim të DataFrame, pa marrë parasysh?

Siç thotë një shprehje e vjetër, "një onsë parandalimi është një pound kurimi." Në një moment, nëse nuk kujdeseni për aplikimin e skemës tuaj, do të lindin probleme të dhimbshme me përputhshmërinë e tipeve të të dhënave — gjithashtu burimet e dukshme të papiruar të dhënash mund të përmbajnë raste të kufizuara, kolona të dëmtuara, përfytyrime të formuara keq ose gjëra të tjera të frikshme që ndodhin në pesimizmat tuaj. Qasja më e mirë është të ndaloni këta armiq te portat — përmes aplikimit të detyrueshëm të skemave — dhe të merremi me ta në dritë, dhe jo më vonë, kur ata fillojnë të përhapen në thellësitë e errëta të kodit tuaj të punës.

Aplikimi i detyrueshëm i skemës ofron sigurinë që skema e tabelës suaj nuk do të ndryshojë, përveç nëse e konfirmoni vetë ndryshimin. Kjo parandalon 'njollosjen' (dilution) e të dhënave, e cila ndodh kur kolonat e reja shtohen aq shpesh, sa tabelat e mëparshme, të vlefshme dhe të kompresuara humbasin vlerën dhe përdorshmërinë e tyre për shkak të përmbytjes nga të dhënat. Duke ju inkurajuar të jeni të qëllimshëm, të vendosni standarde të larta dhe të prisni cilësi të lartë, aplikimi i detyrueshëm i skemës e bën pikërisht atë për çfarë është të destinuar - të ndihmojë që ju të mbani një qëndrim të ndershëm dhe tabelat tuaja të mbeten të pastra.

Nëse gjatë shqyrtimit të mëtejshëm vendosni se ju nevojitet të shtoni një kolonë të re - asnjë problem, më poshtë është një zgjidhje e thjeshtë një-linjëshe. Zgjidhja është evolucioni i skemës! Çfarë është evolucioni i skemës?

Evolucioni i skemës është një funksion që lejon përdoruesit të ndryshojnë lehtësisht skemën aktuale të tabelës në përputhje me të dhënat që ndryshojnë me kalimin e kohës. Përdoret më së shpeshti në operacionet e shtimit ose të ridëshirimit, për të përshtatur automatikisht skemën për të përfshirë një ose disa kolona të reja.

Si funksionon evolucioni i skemës?

Duke ndjekur shembullin nga seksioni i mëparshëm, zhvilluesit mund të përdorin lehtësisht evolucionin e skemës për të shtuar kolona të reja që më parë ishin refuzuar për shkak të moskonsistencës me skemën. Evolucioni i skemës aktivizohet duke shtuar

.option('mergeSchema', 'true') në komandën tuaj Spark .write ose .writeStream. Për të parë grafikun, ju lutemi ekzekutoni këtë kërkesë Spark SQL

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

Si një alternativë, mund ta vendosni këtë opsion për tërë sesionin Spark, duke shtuar

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

The Role of Delta Lake: Schema Enforcement and Evolution
spark.databricks.delta.schema.autoMerge = True në konfigurimin e Spark. Por përdoreni këtë me kujdes, pasi aplikimi i detyrueshëm i skemës nuk do t'ju paralajmërojë më për moskonsistencat e paqëllimshme me skemën. Duke përfshirë parametrin

mergeSchema në kërkesë, të gjitha kolonat që janë të pranishme në DataFrame, por mungojnë në tabelën e synuar, shtohen automatikisht në fund të skemës si pjesë e transaksionit të shkrimit. Po ashtu mund të shtohen fusha të përfshira, dhe ato gjithashtu do të shtohen në fund të kolonave përkatëse të strukturës., все столбцы, которые присутствуют в DataFrame, но отсутствуют в целевой таблице, автоматически добавляются в конец схемы в рамках транзакции записи. Также могут быть добавлены вложенные поля, и они также будут добавлены в конец соответствующих столбцов структуры.

Inxhinierët dhe shkencëtarët mund të përdorin këtë opsion për të shtuar kolonat e reja (ndoshta një metrikë të ndjekur rishtazi ose një kolone treguesish për shitjet këtë muaj) në tabelat e tyre ekzistuese të prodhimit të mësimit të makinerive, pa e prishur modelet ekzistuese që bazohen në kolonat e vjetra.

Llojet e mëposhtme të ndryshimeve të skemës janë të lejuara në kuadrin e evolucionit të skemës gjatë shtimit ose rihapjes së tabelës:

  • Shtimi i kolonave të reja (kjo është skenari më i zakonshëm)
  • Ndryshimi i llojeve të të dhënave nga NullType -> çdo lloj tjetër ose rritja nga ByteType -> ShortType -> IntegerType

Ndryshime të tjera, të papranueshme në kuadrin e evolucionit të skemës, kërkojnë që skema dhe të dhënat të rivendosen duke shtuar .option("overwriteSchema", "true"). Për shembull, në rastin kur kolona "Foo" fillimisht ishte integer dhe skema e re do të ishte e tipit string, atëherë të gjithë skedarët Parquet (të dhënat) duhet të rivendosen. Ndryshimet e tilla përfshijnë:

  • fshirjen e kolonës
  • ndryshimin e llojit të të dhënave të një kolone ekzistuese (në vend)
  • rilodhjen e kolonave që ndryshojnë vetëm në regjistrin (p.sh., "Foo" dhe "foo")

Së fundi, me lëshimin e ardhshëm të Spark 3.0, do të përkrahë plotësisht DDL të qartë (duke përdorur ALTER TABLE), që do të lejojë përdoruesit të realizojnë veprimet e mëposhtme mbi skemat e tabelave:

  • shtimi i kolonave
  • ndryshimi i komenteve për kolonat
  • konfigurimi i pronave të tabelës që përcaktojnë sjelljen e tabelës, për shembull, vendosja e kohëzgjatjes së ruajtjes së regjistrit të transaksioneve.

Cila është dobi e evolucionit të skemës?

Evolucioni i skemës mund të përdoret gjithmonë kur ju keni ndërmend të ndryshoni skemën e tabelës tuaj (në kontrast me ato raste kur aksidentalisht keni shtuar në DataFrame-in tuaj kolona që nuk duhej të ishin atje). Kjo është mënyra më e thjeshtë për të migruar skemën tuaj, sepse automatikisht shton emrat e duhur të kolonave dhe llojet e të dhënave pa nevojën për t'i shpallur ato qartë.

Përfundim

Zbatimi i detyrueshëm i skemës hedh poshtë çdo kolone të re ose ndryshime të tjera të skemës që nuk janë të përshtatshme për tabelën tuaj. Duke vendosur dhe mbajtur këto standarde të larta, analistët dhe inxhinierët mund të mbështeten në të dhënat e tyre që kanë një nivel të lartë integriteti, duke e argumentuar këtë qartë dhe saktë, duke u mundësuar atyre të marrin vendime më efektive biznesi.

Nga ana tjetër, evolucioni i skemës plotëson zbatimin e detyrueshëm, duke e bërë më të lehtë shkallëzimin automatik të ndryshimeve të skemës. Në fund të fundit, kjo nuk duhet të jetë një kompleksitet — për të shtuar një kolonë.

Zbatimi i detyrueshëm i skemës është jani, ku evolucioni i skemës është inni. Kur përdoren së bashku, këto funksione e thjeshtojnë ndihmën dhe konfigurimin e sinjalit si asnjëherë më parë.

Gjithashtu, do donim të falenderonim Mukul Murti dhe Pranav Anand për kontributin e tyre në këtë artikull.

Artikuj të tjerë nga kjo seri:

Zhytesha në Delta Lake: shpërndarja e regjistrit të transaksioneve

Luaj videon

Artikuj lidhur me temën

Mësimi i makinerisë në nivel prodhimi me Delta Lake

Çfarë është një liqen të dhënash?

Mësoni më shumë rreth kursit

Burimi: habr.com

Bleni hostin e besueshëm për faqet me mbrojtje nga DDoS, VPS VDS servera 🔥 Bli hostin e besueshëm për faqet me mbrojtje nga DDoS, VPS VDS servera | ProHoster