Коротко: Delta Lake — це open-source storage framework поверх Parquet-файлів у data lake або lakehouse, який додає ACID-транзакції, schema enforcement, versioning, time travel та підтримку UPDATE, DELETE і MERGE. Ключова концепція — transaction log у директорії _delta_log: саме він фіксує зміни таблиці й дозволяє читати консистентні версії даних. Тема актуальна для data engineers, аналітиків і команд, які будують надійні data pipeline-и на S3, ADLS, GCS, Databricks або Microsoft Fabric.

Вступ

Delta Lake з’явився як відповідь на одну з найпоширеніших проблем у роботі з даними: data lake, який починався як впорядковане сховище, поступово перетворюється на хаос із дублями, зламаними pipeline-ами та неконсистентними читаннями.

Delta Lake вирішує це через transaction log поверх звичайних Parquet-файлів. Дані фізично залишаються у Parquet, але поряд із ними з’являється метаданний шар, який описує, які файли належать до поточної версії таблиці, які були видалені логічно, яка схема є актуальною і які операції виконувалися раніше.

У цій статті розберемо, як влаштовані Delta-таблиці зсередини, як працює versioning і time travel, де Delta Lake використовується на практиці і які обмеження варто знати перед тим, як впроваджувати його у свій стек.

Що таке Delta Lake і чому він з’явився?

Проблема звичайного data lake: дані є, порядку немає

Класична ситуація в командах: є S3-бакет, ADLS-контейнер або інше об’єктне сховище із сотнями Parquet-файлів, кілька pipeline-ів пишуть дані паралельно, і в якийсь момент читання повертає неконсистентні результати. Один pipeline упав посередині запису — частина файлів уже створена, частини ще немає. Схема змінилась без попередження — downstream-таблиці або звіти можуть зламатися.

Звичайний data lake на рівні файлів не має таблицевого transaction log. Об’єктне сховище на кшталт S3, ADLS або GCS зберігає файли, але саме по собі не знає, які з них утворюють актуальну логічну таблицю, яку схему потрібно застосовувати та які файли треба ігнорувати після UPDATE або DELETE.

Delta Lake як відповідь на хаос у сховищах даних

Delta Lake був створений Databricks і розвивається як open-source проєкт у межах LF AI & Data Foundation. Його ідея — зробити data lake на Parquet надійнішим: додати транзакційність, контроль схеми, versioning і time travel без переходу на закритий формат зберігання.

Принцип роботи такий: Parquet-файли залишаються у сховищі, але поруч з’являється директорія _delta_log. Вона містить JSON-файли та checkpoint-файли з інформацією про коміти. Саме цей лог визначає, які файли є актуальними, які були логічно видалені, яка схема діє зараз і яку версію таблиці потрібно прочитати.

Як влаштовані Delta Lake таблиці зсередини?

Структура Delta таблиці: Parquet + _delta_log

Фізично Delta-таблиця виглядає так:

my_table/

├── part-00000-abc123.parquet

├── part-00001-def456.parquet

├── part-00002-ghi789.parquet

└── _delta_log/

    ├── 00000000000000000000.json

    ├── 00000000000000000001.json

    ├── 00000000000000000002.json

    └── 00000000000000000010.checkpoint.parquet

Кожен JSON у _delta_log описує зміну стану таблиці. У ньому можуть бути такі дії:

  • commitInfo — метадані операції: тип, timestamp, engine, user або job;
  • add — файли, які стали частиною нової версії таблиці;
  • remove — файли, які більше не входять до актуального snapshot таблиці;
  • metaData — схема таблиці, partition columns і конфігурація;
  • protocol — мінімальні версії reader/writer, потрібні для роботи з таблицею.

Transaction log: серце всієї системи

Transaction log — це послідовна історія змін таблиці. Коли Spark або інший сумісний engine читає Delta-таблицю, він спочатку аналізує лог, формує актуальний snapshot таблиці, визначає потрібний набір Parquet-файлів і тільки після цього читає самі дані.

Це дає isolation на рівні таблиці: читач бачить консистентний snapshot, навіть якщо паралельно виконується новий запис. Незавершені або конфліктні зміни не стають частиною таблиці без успішного коміту.

Checkpoint-файли: оптимізація читання лога

Якщо таблиця має сотні або тисячі комітів, перечитувати всі JSON-файли з початку історії неефективно. Для цього Delta Lake створює checkpoint-файли у форматі Parquet, які містять знімок стану transaction log на певну версію. Під час читання engine бере останній checkpoint і дочитує лише JSON-коміти після нього.

Delta Lake vs Parquet: у чому реальна різниця?


Можливість



Parquet без таблицевого шару



Delta Lake


ACID-транзакції

Ні на рівні логічної таблиці

Так

Schema enforcement

Ні, потрібна зовнішня перевірка

Так

Schema evolution

Переважно вручну або через engine

Так, у підтримуваних сценаріях

Time travel

Ні

Так, доки збережені потрібні log і data files

UPDATE / DELETE / MERGE

Ні як table-level операції

Так

Streaming + batch

Потрібна окрема логіка керування файлами

Підтримується через Delta table abstraction

Аудит змін

Ні на рівні таблиці

Базова історія через transaction log

Важливий нюанс щодо UPDATE, DELETE і MERGE: Delta Lake не змінює Parquet-файл “на місці”. Зазвичай він записує нові файли з оновленими даними і позначає старі як remove у transaction log. Це copy-on-write підхід: старі файли фізично залишаються у сховищі до VACUUM, тому time travel може читати попередні версії таблиці.

# Створення Delta таблиці через PySpark
from pyspark.sql import SparkSession

spark = SparkSession.builder \
    .appName("delta-example") \
    .config("spark.jars.packages", "io.delta:delta-spark_<SCALA_VERSION>:<DELTA_VERSION>") \
    .config("spark.sql.extensions", "io.delta.sql.DeltaSparkSessionExtension") \
    .config("spark.sql.catalog.spark_catalog", "org.apache.spark.sql.delta.catalog.DeltaCatalog") \
    .getOrCreate()

# Запис даних у форматі Delta
df.write.format("delta").save("/path/to/my_table")

# Читання Delta таблиці
df = spark.read.format("delta").load("/path/to/my_table")

ACID-транзакції та versioning у Delta Lake: як це реально працює?

Що означає ACID у контексті data lake

ACID у Delta Lake — це набір гарантій на рівні таблиці:

  • Atomicity — або весь батч записався повністю, або нічого. Якщо pipeline впав посередині, таблиця залишається в попередньому консистентному стані.
  • Consistency — таблиця переходить між валідними станами; schema enforcement допомагає відхиляти записи з несумісною схемою.
  • Isolation — читання не бачить незавершених записів. Паралельні операції не заважають одна одній.
  • Durability — після успішного коміту дані та відповідний запис у transaction log зберігаються у надійному сховищі, наприклад S3, ADLS або GCS.

Optimistic concurrency control: як Delta вирішує конфлікти

Delta Lake використовує optimistic concurrency control: writers можуть працювати паралельно, але під час коміту система перевіряє, чи не конфліктують їхні зміни. Якщо операції торкаються незалежних файлів або партицій, вони можуть завершитися успішно. Якщо writers змінюють один і той самий набір файлів або метадані таблиці, один із комітів може отримати конфлікт і має бути повторений.

На практиці це означає: архітектура партиціонування таблиці безпосередньо впливає на можливість паралельних записів.

Schema enforcement і schema evolution

Schema enforcement означає, що Delta Lake перевіряє відповідність даних поточній схемі таблиці. Якщо upstream-джерело змінило структуру або типи колонок несумісним способом, запис може бути відхилений замість того, щоб непомітно зламати downstream-звіти чи pipeline-и.

# Schema evolution — додавання нових колонок
df_new.write \
    .format("delta") \
    .option("mergeSchema", "true") \
    .mode("append") \
    .save("/path/to/my_table")

Опція mergeSchema дозволяє додавати нові колонки під час append або overwrite-сценаріїв, якщо така зміна сумісна з правилами schema evolution. Для вже наявних рядків значення в нових колонках будуть NULL. Водночас schema evolution не означає, що будь-яку зміну схеми можна безпечно застосувати автоматично.

Delta Lake versioning і data governance

Кожен коміт у transaction log містить інформацію про те, що змінилося, коли і якою операцією. Це дає базову історію змін таблиці. Для повноцінного enterprise-аудиту, прав доступу, lineage і governance зазвичай потрібні додаткові інструменти, наприклад Unity Catalog у Databricks або governance-механізми конкретної платформи.

Delta Lake time travel: як читати дані з минулого?

Що таке time travel і навіщо він потрібен

Time travel — це читання таблиці станом на конкретну версію або timestamp. Delta Lake використовує transaction log, щоб визначити, які Parquet-файли входили до snapshot таблиці на той момент. Окрема повна копія таблиці для кожної версії не створюється, але старі файли мають фізично залишатися у сховищі; після VACUUM частина історії може стати недоступною.

Практичне застосування ширше, ніж здається на перший погляд:

  • Відладка pipeline-ів — порівняти стан таблиці до і після трансформації
  • Аудит бізнес-звітів — відтворити дані, які бачив звіт у конкретний день
  • Reproducibility ML-моделей — зафіксувати версію датасету для тренування
  • Відновлення після помилкового DELETE або UPDATE

Time travel за версією та за timestamp: синтаксис і приклади

-- Читання за номером версії (SQL)
SELECT * FROM my_table VERSION AS OF 5;

-- Читання за timestamp (SQL)
SELECT * FROM my_table TIMESTAMP AS OF '2026-01-15';

-- Перегляд історії таблиці
DESCRIBE HISTORY my_table;

# PySpark DataFrame API
# За версією
df = spark.read.format("delta") \
    .option("versionAsOf", 5) \
    .load("/path/to/my_table")

# За timestamp
df = spark.read.format("delta") \
    .option("timestampAsOf", "2026-01-15") \
    .load("/path/to/my_table")

RESTORE TABLE: повернення таблиці до попереднього стану

-- Повернення таблиці до версії 3
RESTORE TABLE my_table TO VERSION AS OF 3;

-- Повернення за timestamp
RESTORE TABLE my_table TO TIMESTAMP AS OF '2026-01-10';

RESTORE створює новий коміт у transaction log — він не видаляє історію, а додає новий запис, який відповідає стану попередньої версії.

Скільки версій зберігається і як керувати retention

У Delta Lake важливо розрізняти два типи retention. delta.deletedFileRetentionDuration визначає, як довго VACUUM зберігає старі data files, які більше не входять до актуальної версії таблиці; типовий поріг — 7 днів. delta.logRetentionDuration визначає, як довго зберігається історія transaction log; типовий період — 30 днів.

-- Налаштування retention
ALTER TABLE my_table SET TBLPROPERTIES (
    'delta.logRetentionDuration' = 'interval 30 days',
    'delta.deletedFileRetentionDuration' = 'interval 30 days'
);

Після виконання VACUUM старі data files можуть бути видалені фізично. Time travel до версій, які потребують цих файлів, стане неможливим. Тому retention-політику потрібно узгоджувати з вимогами до аудиту, відтворюваності ML-експериментів, rollback і SLA pipeline-ів.

Delta Lake у хмарних платформах та інтеграціях

Apache Spark і Delta Lake: нативна інтеграція

Apache Spark залишається одним із головних середовищ виконання для Delta Lake, особливо в екосистемі Databricks, Microsoft Fabric та open-source Spark. Для локального або self-managed старту часто використовують PySpark і бібліотеку delta-spark. Delta Lake підтримує batch і streaming-сценарії, але конкретна реалізація залежить від engine, середовища та доступних функцій.

Microsoft Fabric і Delta Lake: OneLake як lakehouse за замовчуванням

У Microsoft Fabric Delta Lake є стандартним table format для Lakehouse. Коли дані завантажуються в таблиці Lakehouse, Fabric застосовує Delta format автоматично, що спрощує сумісність між Fabric workloads, Power BI, notebooks і pipelines. Тому розуміння Delta Lake корисне для роботи з Fabric на рівні зберігання й оптимізації таблиць.

Databricks, AWS, Azure: де і як використовується Delta Lake

  • Databricks — найглибша інтеграція з Delta Lake: Lakeflow / Delta Live Tables для декларативних pipeline-ів, Unity Catalog для governance, OPTIMIZE, ZORDER, liquid clustering, Change Data Feed та UniForm у підтримуваних сценаріях.
  • AWS — Delta Lake на S3 через Amazon EMR, AWS Glue, Databricks on AWS або self-managed Spark.
  • Azure — ADLS Gen2 + Azure Databricks, Microsoft Fabric або Spark-середовища, які підтримують Delta Lake.

Open Table Formats — коротко про альтернативи:


Формат



Сильна сторона



Типовий стек


Delta Lake

Сильна інтеграція зі Spark, Databricks і Microsoft Fabric; time travel, MERGE, schema enforcement

Spark, Databricks, Fabric, delta-rs та сумісні engines

Apache Iceberg

Мультиенджинність, catalog-driven підхід, сильна підтримка в Trino/Flink/Snowflake-сценаріях

Trino, Flink, Spark, Snowflake, BigQuery у підтримуваних сценаріях

Apache Hudi

Incremental processing, upserts, CDC-орієнтовані сценарії

Spark, Flink, Hive, incremental pipelines

Вибір між Delta Lake, Apache Iceberg і Apache Hudi залежить від engine-ів, governance, сценаріїв оновлення, latency-вимог і платформи. Якщо стек побудований навколо Spark, Databricks або Microsoft Fabric, Delta Lake часто є природним вибором. Якщо потрібна широка мультиенджинність із Trino, Flink, Snowflake або іншими catalog-driven сценаріями, Apache Iceberg може бути зручнішим. Для incremental processing і CDC-сценаріїв варто окремо оцінити Apache Hudi.

Типові помилки та обмеження Delta Lake, про які варто знати

VACUUM без обережності: як втратити можливість time travel

VACUUM видаляє фізичні data files, які більше не є частиною актуальної версії таблиці та старші за retention-поріг. Якщо свідомо відключити safety check і запустити VACUUM із дуже малим retention, старі файли можуть бути видалені, а time travel до відповідних версій стане неможливим. Це особливо небезпечно для таблиць, які читають довгі streaming jobs або використовують для аудиту.

# Небезпечний варіант — тільки якщо ви точно розумієте наслідки
spark.conf.set("spark.databricks.delta.retentionDurationCheck.enabled", "false")
delta_table.vacuum(0)

Безпечніший підхід — налаштувати retention через TBLPROPERTIES, не відключати safety check без крайньої потреби й запускати VACUUM із retention, який відповідає вашим вимогам до time travel, rollback, streaming readers і аудиту. Типовий мінімальний поріг для видалених data files — 168 годин, тобто 7 днів.

Дрібні файли (small files problem) і як з цим боротися

Часті streaming-записи або погано налаштовані batch-и генерують тисячі дрібних Parquet-файлів. Це уповільнює читання, бо Spark витрачає час на відкриття кожного файлу окремо.

У Databricks типове рішення — OPTIMIZE, ZORDER або liquid clustering залежно від runtime, таблиці та патернів запитів:

-- Компактація дрібних файлів
OPTIMIZE my_table;

-- ZORDER для co-location пов'язаних даних
OPTIMIZE my_table ZORDER BY (user_id, event_date);

OPTIMIZE компактує дрібні файли у більші через bin-packing. ZORDER допомагає розмістити пов’язані значення ближче одне до одного, щоб data skipping читав менше файлів для фільтрів по вибраних колонках. У новіших Databricks-сценаріях також варто враховувати liquid clustering, який може замінювати або доповнювати ручну оптимізацію layout.

Коли Delta Lake — не найкращий вибір

Delta Lake добре підходить для аналітичних pipeline-ів на хмарних сховищах. Але є сценарії, де інші рішення доцільніші:

  • OLTP з тисячами дрібних транзакцій за секунду — для цього існують реляційні бази даних.
  • Sub-second latency — Delta Lake не призначений для real-time систем із затримкою менше секунди.
  • Прості аналітичні задачі — якщо pipeline читає статичні дані без оновлень, звичайний Parquet може бути достатнім.
  • High-throughput concurrent writers на одну партицію — потребує ретельного архітектурного планування, інакше ConcurrentModificationException стане регулярним явищем.

FAQ: питання про Delta Lake

Питання: Що таке Delta Lake?

Відповідь: Delta Lake — це open-source storage framework поверх Parquet, який додає ACID-транзакції, schema enforcement, schema evolution, versioning, time travel і підтримку UPDATE, DELETE та MERGE до data lake. Він не замінює хмарне сховище, а додає над ним таблицевий transaction log. Delta Lake активно використовується в екосистемі Spark, Databricks і Microsoft Fabric, але його також можна читати іншими сумісними engine-ами залежно від підтримки конкретної платформи.

Питання: Як почати роботу з Delta Lake?

Відповідь: Для локального старту можна встановити delta-spark і підключити її до Spark-сесії. Далі DataFrame можна записувати у форматі delta замість parquet. Якщо не хочеться налаштовувати локальне середовище, у 2026 році для навчання варто орієнтуватися на Databricks Free Edition, яка замінила legacy Community Edition. Вона підходить для навчання, прототипування й експериментів, але не для production-навантажень.

Питання: Delta Lake vs Apache Iceberg — що краще для data lakehouse?

Відповідь: Обидва формати вирішують схожі задачі: ACID-транзакції, versioning, schema evolution і управління таблицями в data lake. Delta Lake часто є природним вибором для стеків Databricks, Microsoft Fabric і Spark. Apache Iceberg сильний у мультиенджинних середовищах, де поруч працюють Trino, Flink, Snowflake або інші query engines. Databricks також розвиває UniForm: він генерує Iceberg metadata для Delta-таблиць, щоб Iceberg clients могли читати ті самі Parquet data files без переписування даних.

Питання: Чи є Delta Lake безкоштовним?

Відповідь: Delta Lake — open-source проєкт під ліцензією Apache 2.0. Сам storage framework і бібліотеки доступні безкоштовно. Платити доведеться за хмарне сховище, обчислення, Spark-кластер або керовану платформу. У Databricks частина enterprise-функцій, governance, serverless compute та platform features доступні в платних тарифах, а для навчання можна використовувати Databricks Free Edition.

Питання: Які помилки роблять при роботі з Delta Lake?

Відповідь: Найпоширеніші помилки — запускати VACUUM без розуміння retention і time travel, неправильно обирати partition columns, створювати тисячі дрібних файлів, змішувати Delta і non-Delta файли в одній директорії, неконтрольовано вмикати schema evolution і не перевіряти конфлікти паралельних записів. VACUUM важливий для контролю вартості сховища, але його потрібно запускати з retention-політикою, яка не ламає аудит, rollback і streaming-сценарії.

Висновок

Delta Lake вирішує реальні проблеми, з якими стикаються команди при роботі з data lake: неконсистентні читання, зламані pipeline-и після зміни схеми, відсутність аудиту змін.

Transaction log — це ключова концепція, яку варто зрозуміти першою. Решта можливостей — time travel, versioning, schema enforcement — виростає саме з нього.

Сьогодні Delta Lake є стандартним table format у Microsoft Fabric Lakehouse і одним із ключових форматів у lakehouse-архітектурах Databricks та Spark-екосистеми. Почати можна локально через delta-spark або в керованому середовищі на кшталт Databricks Free Edition чи Microsoft Fabric, але для production-сценаріїв важливо одразу продумати retention, governance, оптимізацію файлів і права доступу.