Arhitectura datelor și a sistemelor, de la zero Lecția 37 / 80

Lakehouses: Delta, Iceberg, Hudi

Tranzacții ACID peste object storage. Războiul formatelor din 2023-2025 și unde a ajuns industria în 2026.

Lecția precedentă a descris cum sunt organizate datele în interiorul unui lake (bronze, silver, gold). Lecția asta e despre din ce e făcut de fapt lake-ul în 2026. Mai exact: ce format de fișier folosesc tabelele alea, și de ce folosim altceva decât Parquet curat pe object storage?

Răspunsul scurt e formatele de tabel pentru lakehouse: Delta Lake, Apache Iceberg și Apache Hudi. Sunt stratul care transformă un folder de fișiere Parquet pe S3 în ceva care se comportă ca un tabel de bază de date, cu tranzacții ACID, evoluție de schemă, time travel și citiri și scrieri concurente. Sunt tehnologia care a făcut ca termenul „lakehouse” să nu mai fie marketing și să devină un tipar arhitectural real.

Cele trei formate au petrecut anii dintre 2019 și 2025 într-o încleștare competitivă, fiecare furnizor împingând câte unul ca fiind viitorul. Până în 2026 praful s-a așezat în mare parte, iar lecția asta spune povestea fiecăruia, ce au în comun și cum arată tabloul din 2026 pentru cineva care alege între ele azi.

De ce Parquet curat pe S3 nu e suficient

Parquet e un format de fișier columnar. E rapid, comprimat și bine suportat de fiecare engine de analiză. Instinctul, când construiești prima dată un data lake, e să scrii fișiere Parquet în S3 și să le citești înapoi cu Spark, Trino sau DuckDB. Pentru un workload cu un singur writer și doar append, asta merge bine.

Problema începe în clipa în care ai mai mult de un writer, sau orice update care nu e un append curat.

  • Fără tranzacții. Dacă două job-uri scriu în aceeași partiție în același timp, își suprascriu reciproc fișierele. Nu există o operație atomică „adaugă fișierele astea noi și șterge-le pe alea vechi”.
  • Fără înlocuire atomică de partiție. Tiparul „suprascrie partiția asta” (lecția 38) cere ștergerea fișierelor vechi și scrierea celor noi. Dacă un reader interoghează în fereastra dintre ștergere și scriere, vede o imagine parțială a datelor sau deloc.
  • Fără ștergeri la nivel de rând. GDPR îți cere să ștergi înregistrările unui anumit utilizator. Cu Parquet brut trebuie să găsești fiecare fișier care conține rândurile lui, să rescrii fiecare fără rândurile șterse și să le înlocuiești. Nu există niciun mecanism nativ pentru toate astea.
  • Fără evoluție de schemă. Adăugarea unei coloane înseamnă rescrierea fiecărui fișier din tabel, sau acceptarea unei harababuri de tip schema-on-read în care unele fișiere au coloana și altele nu.
  • Fără time travel. „Arată-mi tabelul așa cum era marțea trecută” e o întrebare la care Parquet brut nu are răspuns, decât dacă s-a întâmplat să păstrezi snapshot-uri.
  • Fără statistici care se actualizează. Fiecare fișier Parquet are statisticile lui, dar nu există un strat de metadate la nivel de tabel pe care engine-ul de query să-l folosească pentru a sări fișierele cu eleganță.

Formatele de tabel pentru lakehouse sunt stratul care rezolvă toate astea. Stau peste fișierele Parquet (datele propriu-zise sunt tot Parquet) și adaugă un strat de metadate care înregistrează care fișiere aparțin tabelului la care moment în timp. Citirile consultă metadatele pentru a ști ce fișiere să scaneze. Scrierile actualizează metadatele atomic. Doi writers nu se corup reciproc; se aliniază la stratul de metadate și se serializează.

Asta e toată ideea. Diferențele dintre Delta, Iceberg și Hudi țin de cum e structurat stratul de metadate și ce funcționalități expune.

Delta Lake

Delta Lake a fost pus în open-source de Databricks în 2019. Stratul de metadate e un transaction log: un director de fișiere JSON (cu checkpoint-uri Parquet periodice) care înregistrează fiecare commit pe tabel. Fiecare commit e o operație atomică ce adaugă și șterge fișiere. Cititorii consultă log-ul pentru a calcula setul curent de fișiere; scriitorii adaugă în log pentru a face modificări.

Punctele forte ale Delta:

  • Integrare strânsă cu Spark. Delta a fost proiectat alături de Spark Structured Streaming, iar traseul streaming-spre-Delta e cel mai șlefuit dintre cele trei formate. Dacă ingestia ta e „Kafka în tabel bronze prin Structured Streaming”, Delta e calea cea mai ușoară.
  • Sintaxă MERGE. MERGE INTO ... USING ... ON ... a fost prima livrată în Delta și e încă cea mai ergonomică implementare. Upsert-urile în stil CDC sunt cetățeni de prima clasă.
  • Vacuum și Z-ORDER. Delta are implementări solide de compactare a fișierelor (OPTIMIZE) și clustering multidimensional (ZORDER BY). Pentru workload-urile Spark, povestea de mentenanță e bună.
  • Susținut de Databricks. Platforma pe care e cel mai probabil să rulezi Delta are cea mai profundă integrare posibilă. Pe Databricks, „folosește Delta” e calea cu cea mai mică rezistență și aproape întotdeauna răspunsul corect.

Slăbiciunea istorică a Delta era că versiunea open-source rămânea în urma celei de pe Databricks, iar suportul pentru engine-uri în afara Spark era mai subțire decât al Iceberg. Ambele s-au îmbunătățit prin 2024 și 2025: versiunea open-source e mai aproape de paritate funcțională, iar Delta UniForm e un strat de compatibilitate care expune tabelele Delta ca fiind citibile ca Iceberg, închizând parțial decalajul cross-engine.

Apache Iceberg

Apache Iceberg a ieșit de la Netflix în 2018 și a fost donat fundației Apache. A fost proiectat de la început pentru independența față de engine-ul de query. Stratul de metadate e mai elaborat decât cel al Delta: un arbore de fișiere de metadate (table metadata, manifest lists, manifests) care înregistrează snapshot-urile tabelului, schemele, specificațiile de partiționare și listele de fișiere. Structura e mai voluminoasă decât log-ul Delta, iar acea verbozitate e prețul susținerii curate a unei game mai largi de operații.

Punctele forte ale Iceberg:

  • Neutralitatea față de engine. Iceberg e cetățean de prima clasă în Spark, Trino, Flink, Presto, Dremio, Snowflake (din 2024), BigQuery, AWS Glue și Athena, și DuckDB. Dacă vrei să citești același tabel din mai multe engine-uri, Iceberg are de departe cea mai bună poveste.
  • Hidden partitioning. Iceberg îți permite să declari partiționarea ca transformări pe coloane (days(event_time), bucket(16, user_id)) fără a le expune în schema vizibilă utilizatorului. Query-urile nu trebuie să știe despre coloanele de partiție; engine-ul împinge filtrele în jos prin transformări automat. E unul dintre cele mai mari câștiguri ergonomice față de Delta.
  • Evoluție de schemă și de partiție. Iceberg poate evolua specificația de partiție fără rescrierea datelor vechi. Fișierele vechi își păstrează layout-ul vechi, fișierele noi folosesc layout-ul nou, iar citirile funcționează peste graniță. Delta nu poate face asta fără rescriere.
  • Poveste solidă de guvernanță. Ecosistemul de cataloage (Nessie, Polaris, AWS Glue catalog, suportul Iceberg din Unity Catalog) s-a maturizat în jurul Iceberg. Guvernanța multi-engine e zona în care Iceberg e cu adevărat liderul.

Slăbiciunea istorică a Iceberg era că povestea de scriere streaming rămânea în urma celei a Delta, iar gestionarea fișierelor mici cerea mai multă grijă manuală. Ambele s-au îmbunătățit.

Apache Hudi

Apache Hudi a ieșit de la Uber în 2017, cel mai vechi dintre cele trei. Centrul lui de design e upsert-urile și procesarea incrementală. Hudi e formatul construit în jurul ideii de „am un flux CDC dintr-o bază de date și vreau un tabel interogabil care să-l oglindească, cu update-uri aplicate rând cu rând”.

Punctele forte ale Hudi:

  • Upsert-first. Hudi are două tipuri de tabel, Copy-on-Write și Merge-on-Read. Merge-on-Read întreține un fișier de bază plus un log de update-uri la nivel de rând, cu compactare periodică. Pentru workload-uri cu frecvență mare de update-uri pe înregistrări individuale (oglindiri CDC, dimensiuni cu schimbare lentă), e mai eficient decât rescrierea fișierelor întregi.
  • Query-uri incrementale. Hudi are suport de prima clasă pentru „dă-mi rândurile care s-au schimbat de la timestamp T”, care e primitiva naturală pentru pipeline-urile downstream care vor să consume doar delta-urile.
  • Unelte de ingestie streaming. Hudi Streamer (fost DeltaStreamer) e o unealtă împachetată de ingestie streaming pentru surse comune (Kafka, JDBC CDC), cu deduplicare și semantică de upsert încorporate.

Slăbiciunea Hudi, în 2026, e că use case-urile la care strălucește sunt și cele unde Iceberg a recuperat substanțial, iar în afara lor suportul mai larg din ecosistem e mai subțire. Hudi e alegerea potrivită pentru workload-uri dominate de streaming-upsert, mai ales când deja știi că tiparul ăla domină. Rar e alegerea potrivită ca default general.

Ce au în comun

Pentru decizia arhitecturală de nivel înalt, cele trei formate sunt mai degrabă similare decât diferite. Toate trei îți dau:

  • Tranzacții ACID peste object storage. Scrierile concurente sunt serializate prin stratul de metadate. Cititorii văd un snapshot consistent.
  • Evoluție de schemă. Adaugă o coloană. Redenumește o coloană. Schimbă tipul unei coloane între familii compatibile. Stratul de metadate ține istoricul.
  • Time travel. Interoghează tabelul așa cum era la timestamp T sau la versiunea V. Metadatele păstrează snapshot-urile vechi până sunt expirate explicit.
  • Semantica MERGE / upsert. Inserează rânduri noi, actualizează rânduri existente, șterge rânduri potrivite, totul atomic.
  • Citiri și scrieri concurente. Query-urile care rulează mult văd un snapshot stabil în timp ce scrierile avansează.
  • Ștergeri la nivel de rând. Prietenoase cu GDPR. Rulează un DELETE FROM table WHERE user_id = ? și formatul se ocupă de rescrierile de fișiere.

Dacă alegi între ele și oricare dintre funcționalitățile astea înclină balanța, probabil ai citit greșit situația. Funcționalitățile sunt baza minimă obligatorie pe toate cele trei formate acum. Decizia se învârte în jurul potrivirii cu ecosistemul, nu al capabilităților.

Războiul formatelor și unde au ajuns

Între 2022 și 2025, fiecare furnizor cu interes în lakehouse și-a împins formatul preferat. Databricks a împins Delta. Snowflake, AWS și Confluent au împins Iceberg. Onehouse a împins Hudi. Clienții au făcut proof of concept pe toate trei, au scris articole de opinie și s-au întrebat dacă formatul va mai exista în cinci ani.

Până în 2026 tabloul s-a clarificat, în mare parte în favoarea Iceberg. Mișcările pivot au fost integrarea profundă Iceberg de la Snowflake din 2024 (acum poți citi și scrie tabele Iceberg direct din Snowflake), AWS Glue și Athena făcând Iceberg formatul prietenos default și BigQuery expunând Iceberg ca tip de tabel extern complet suportat. Combinația a însemnat că un tabel Iceberg putea fi interogat din Spark, Snowflake, BigQuery, Trino și uneltele native AWS fără ca cineva să fie nevoit să rescrie datele. Acea poveste cross-engine e ce voiau oamenii originali ai lake-urilor în 2018, iar Iceberg e formatul care a livrat-o.

Databricks a răspuns cu Delta UniForm, care scrie tabele Delta într-un mod care le expune ca fiind citibile ca Iceberg pentru alte engine-uri. Pariul e că „Delta pe Databricks, citibil ca Iceberg din afară” e suficient pentru use case-ul cross-engine fără a abandona funcționalitățile native ale Delta. În 2026 funcționează destul de bine pentru majoritatea scenariilor de citire, mai puțin lin pentru scrieri, iar traiectoria e pozitivă.

Hudi rămâne alegerea cea mai bună pentru workload-ul streaming-upsert pentru care a fost construit, și un ecosistem mai mic în rest.

flowchart LR
    K[Kafka, CDC, files] --> I[Bronze: Iceberg or Delta]
    I --> SP[Spark transforms]
    SP --> S[Silver: Iceberg or Delta]
    S --> DBT[dbt models]
    DBT --> G[Gold: Iceberg or Delta]
    G --> Q1[Spark]
    G --> Q2[Trino]
    G --> Q3[Snowflake]
    G --> Q4[BigQuery]
    G --> Q5[DuckDB]

Unde se potrivește fiecare în 2026

Un ghid practic pentru 2026:

  • Ești pe Databricks. Folosește Delta. Integrarea e excelentă, fiecare funcționalitate Databricks presupune Delta, iar UniForm îți dă citibilitate externă cu aromă de Iceberg când ai nevoie.
  • Începi un lakehouse nou, multi-engine sau neutru față de furnizor. Folosește Iceberg. E default-ul cel mai sigur, suportul cel mai larg pe engine-uri și cea mai bună poveste de guvernanță pe termen lung. Alegerea „default-ul default-urilor”.
  • Workload-ul tău dominant e oglindiri CDC de frecvență mare cu multe upsert-uri. Privește serios Hudi. Rulează un benchmark pe workload-ul tău real înainte să te angajezi.
  • Ai deja Delta sau Iceberg funcționând. Nu schimba doar ca să fii pe formatul „câștigător”. Migrările sunt muncă reală de inginerie, iar diferențele nu sunt suficient de mari ca să le justifice decât dacă o funcționalitate specifică te blochează.

Cursul de PySpark, în modulul 8, are o lecție hands-on care parcurge Delta, Iceberg și Hudi cu cod: setarea tabelelor, executarea de MERGE, time travel, compararea layout-urilor de metadate. Dacă vrei să lucrezi cu formatele în loc să decizi doar între ele, lecția aia e următoarea oprire după asta.

Lecția următoare e despre o proprietate pe care toate cele trei formate o fac mai ușoară ca niciodată: a face job-urile batch idempotente.

Caută