Learning Platform
Глоссарий Troubleshooting
Урок 14.06 · 40 мин
Продвинутый
Apache HudiTable ServicesCompactionCleaningClusteringXTableSparkFlinkPrestoTrinoEcosystem

Table Services и экосистема

В предыдущих уроках мы разобрали внутреннюю архитектуру Hudi: timeline, COW vs MOR, индексы, concurrency control, запросы. Этот урок завершает модуль двумя темами: Table Services — фоновые операции обслуживания таблицы, и экосистема — интеграции с движками, форматами и инструментами.

Table Services — это то, что делает Hudi self-managing: вместо ручного запуска OPTIMIZE/VACUUM (как в Delta Lake), Hudi может выполнять cleaning, compaction и clustering автоматически, в фоновом режиме, параллельно с ingestion.

NOTE

В Уроке 04 мы видели, что async table services — это один из multi-writer сценариев. Compaction и clustering запускаются как отдельные writer’ы и координируются через OCC или NBCC. Это прямое следствие архитектуры concurrency control.

Три Table Service

Hudi предлагает три основных сервиса обслуживания таблицы, каждый решает свою проблему:

Три Table Services Hudi
CompactionТолько для MOR-таблиц. Мержит log files в base file (Parquet). Улучшает read performance за счёт уменьшения merge overhead при snapshot query. Без compaction — snapshot query замедляется с каждым deltacommit.
CleaningУдаляет устаревшие FileSlice, которые больше не нужны ни одному активному reader'у. Аналог VACUUM в Delta Lake. Освобождает storage. Без cleaning — storage растёт неограниченно.
ClusteringРеорганизует данные для оптимального чтения: сортировка, Z-order, объединение мелких файлов. Аналог OPTIMIZE в Delta Lake. Улучшает query performance через data skipping. Для COW и MOR.

Compaction (MOR)

Compaction — критический сервис для MOR-таблиц. Без compaction, log files накапливаются и snapshot query замедляется, потому что каждый FileSlice требует merge всё большего количества log файлов.

Compaction: merge logs → base
До compactionFileSlice состоит из base file (последняя compaction) и N log files (deltacommits). Snapshot query мержит base + log₁ + ... + logₙ. Чем больше N — тем медленнее read.
compaction
После compactionCompaction мержит base + все log files в новый base file (Parquet). Новый FileSlice начинается с чистого base. Snapshot query читает один файл — максимальная скорость.

Стратегии compaction

Стратегии compaction
BoundedIOОграничивает количество compaction per run: обрабатывает не более N FileSlice за раз. Предсказуемое время compaction. Подходит для production с SLA на время выполнения job'а.
UnBoundedIOОбрабатывает все FileSlice, требующие compaction. Полная очистка за один run. Непредсказуемое время — зависит от accumulated logs. Подходит для scheduled off-peak compaction.
LogFileSizeBasedCompactionПриоритизирует FileSlice с наибольшим объёмом log files. Максимальный impact per IO: сначала compactit те FileSlice, где merge overhead максимален.
DayBasedCompactionКомпактит партиции по дневному расписанию. Партиции, изменённые вчера, компактятся сегодня. Подходит для daily batch pipeline с дневной гранулярностью.

Inline vs Async compaction

# Inline compaction (внутри writer процесса)
hoodie.compact.inline=true
hoodie.compact.inline.max.delta.commits=5
# Compaction запускается каждые 5 deltacommits
# Простота: один процесс. Минус: замедляет ingestion.

# Async compaction (отдельный процесс)
hoodie.compact.inline=false
# Compaction запускается отдельным Spark/Flink job
# Параллельно с ingestion. Требует multi-writer (OCC/NBCC).
TIP

Для production рекомендуется async compaction: отдельный Spark-job по расписанию. Inline compaction замедляет ingestion pipeline — каждые N deltacommits writer останавливается для compaction. Async compaction работает параллельно, не влияя на latency записи.

Cleaning

Cleaning удаляет устаревшие FileSlice, которые больше не нужны reader’ам. Это аналог VACUUM в Delta Lake:

Cleaning: удаление устаревших FileSlice
FileGroup fg-001FileGroup содержит несколько FileSlice: исторические (от старых commit'ов) и текущий. Reader видит только текущий FileSlice. Старые FileSlice — orphaned storage.
cleaning
FileGroup fg-001 (cleaned)После cleaning: только текущий FileSlice остаётся. Старые FileSlice удалены — storage освобождён. Cleaning учитывает retention policy: не удаляет FileSlice, которые могут понадобиться для time travel.

Cleaning policies

# Сколько commit'ов сохранять (по умолчанию: 10)
hoodie.cleaner.commits.retained=10

# Policy: KEEP_LATEST_COMMITS — хранить N последних commit'ов
hoodie.cleaner.policy=KEEP_LATEST_COMMITS

# Policy: KEEP_LATEST_FILE_VERSIONS — хранить N версий каждого файла
hoodie.cleaner.policy=KEEP_LATEST_FILE_VERSIONS
hoodie.cleaner.fileversions.retained=3

# Inline cleaning (каждый commit)
hoodie.clean.automatic=true

# Async cleaning (отдельный процесс)
hoodie.clean.automatic=false
WARNING

Cleaning необратим: удалённые FileSlice нельзя восстановить. Time travel на commit’ы до cleaning невозможен. Устанавливайте hoodie.cleaner.commits.retained исходя из требований к time travel и incremental query depth.

Clustering

Clustering реорганизует physical layout данных для оптимизации read performance. Это аналог OPTIMIZE + Z-ORDER в Delta Lake:

Clustering: реорганизация layout
До clusteringФайлы неоптимальны: мелкие файлы от частых upsert, данные не отсортированы по query-колонкам. Data skipping неэффективен — min/max overlap высокий.
clustering
После clusteringФайлы реорганизованы: данные отсортированы по cluster-колонке (region), мелкие файлы объединены. Min/max ranges не перекрываются — data skipping пропускает ненужные файлы.

Parquet Binary Copy: 10-15x ускорение

В Hudi 1.0 появилась оптимизация Parquet Binary Copy для clustering и compaction:

Parquet Binary Copy
Без Binary CopyСтандартный процесс: чтение Parquet → десериализация в Java-объекты → сортировка/merge → сериализация обратно в Parquet → запись. Дорого по CPU: десериализация + сериализация.
С Binary Copy (Hudi 1.0)Оптимизация: копирует Parquet row groups как бинарные блоки, без десериализации. Если row group не нужно модифицировать — прямое копирование. 10-15x ускорение для compaction и clustering больших таблиц.
NOTE

Parquet Binary Copy особенно эффективен для compaction MOR-таблиц с малым количеством изменений: если log files затрагивают 1% записей в base file, 99% row groups копируются бинарно. Это делает compaction практически бесплатной для hot-partition / cold-data сценариев.

XTable: Multi-Format Interop

Apache XTable (incubating) — проект, позволяющий конвертировать метаданные между Hudi, Delta Lake и Iceberg без копирования данных:

XTable: cross-format interop
Hudi Table (source)Hudi-таблица с данными в Parquet файлах и .hoodie/ метаданными. XTable читает .hoodie/ timeline и генерирует метаданные других форматов.
XTable sync
+ Delta metadataXTable генерирует _delta_log/ с JSON commit файлами, описывающими те же Parquet файлы. Presto/Trino с Delta connector читают таблицу как Delta.
+ Iceberg metadataXTable генерирует metadata/ с manifest-файлами и snapshot'ами. Те же Parquet файлы. Presto/Trino с Iceberg connector читают таблицу как Iceberg.

XTable работает in-place: не копирует данные, а генерирует дополнительные метаданные рядом с существующими. Одни и те же Parquet файлы читаются через Hudi connector, Delta connector или Iceberg connector — в зависимости от метаданных, которые видит движок.

# XTable CLI: sync Hudi → Delta + Iceberg
java -jar xtable-utilities.jar \
 --source-format HUDI \
 --target-formats DELTA,ICEBERG \
 --table-base-path s3://bucket/hudi_table/ \
 --sync-mode INCREMENTAL
TIP

XTable решает ту же проблему, что UniForm в Delta Lake: multi-engine access без дублирования данных. Разница: UniForm встроен в Delta (автоматическая генерация Iceberg metadata при commit), а XTable — внешний инструмент, работающий с любым из трёх форматов как source.

Интеграция с движками

Hudi поддерживает Spark, Flink, Presto и Trino как основные движки. Начиная с версии 1.0, все четыре движка — равноправные:

Матрица совместимости движков
Apache SparkИсторически — primary engine. Полная поддержка: read + write, COW + MOR, все query types, table services (compaction/clustering/cleaning). Spark 3.x и 4.0. hudi-spark-bundle JAR.
Apache FlinkSecond primary engine. Streaming-first: delta streamer, real-time ingestion. Полная поддержка MOR + compaction. Flink CDC интеграция. hudi-flink-bundle.
Presto / TrinoRead-only через Hudi connector. Snapshot и read-optimized queries. Partition pruning, predicate pushdown. Нет write support. Hudi 1.0 улучшил metadata-based listing для ускорения planning.
hudi-rs (Python)Нативный Rust-based reader. Snapshot, incremental, time-travel без JVM. PyArrow output. Read-only v0.4.0. Подходит для analytics notebooks и lightweight ETL read-path.

Hudi 1.0 Feature Matrix

Hudi 1.0 (GA декабрь 2024) — крупнейший релиз в истории проекта. Ключевые новые features:

Hudi 1.0: новые возможности
NBCCNon-Blocking Concurrency Control. FileGroup-level isolation для параллельных writer'ов. Заменяет OCC с lock providers. Подробно — в Уроке 04.
Secondary IndexesФункциональные и expression-based индексы. Поверх metadata table. Ускоряют point queries и range queries. Подробно — в Уроке 03.
Partial UpdatesColumn-level merge на MOR-таблицах. Обновление отдельных колонок без перезаписи всей записи. Уменьшает write amplification для wide tables.
LSM TimelineArchived timeline в LSM-формате (compacted Avro). Бесконечный time travel — нет потери истории при архивации. Подробно — в Уроке 01.
Record IndexHFile-based record-level index с кэшированием. До 4x ускорение upsert lookup. Global index без full-table scan. Подробно — в Уроке 03.
Binary CopyParquet row group бинарное копирование. 10-15x ускорение compaction и clustering. Без десериализации. Описано выше в этом уроке.

Сравнение с Delta Lake и Iceberg

Table Services: Hudi vs Delta Lake vs Iceberg
Delta LakeOPTIMIZE (compaction + Z-ORDER/Liquid), VACUUM (cleaning), Predictive I/O (Databricks). Ручной запуск OPTIMIZE/VACUUM. Auto-OPTIMIZE через AutoCompact (Databricks). Нет встроенного async scheduling.
Apache IcebergRewriteDataFiles (compaction/clustering), ExpireSnapshots (cleaning), RemoveOrphanFiles, RewriteManifests. Spark Actions API. Нет встроенного async — scheduling через Airflow/cron.
Apache HudiCompaction (MOR, inline/async), Cleaning (auto/async), Clustering (inline/async). Встроенный scheduling: inline с ingestion или async отдельным процессом. Table services — first-class citizens.

Ключевое отличие Hudi

Hudi — единственный из трёх форматов, где table services встроены в runtime как первоклассные операции. Delta Lake и Iceberg рассматривают compaction/vacuum как отдельные команды, запускаемые пользователем. Hudi рассматривает их как автоматические сервисы, координируемые с ingestion через timeline.

Итоговое сравнение трёх форматов
Delta LakeDatabricks-backed. Transaction log (_delta_log/). OCC через atomic rename / Coordinated Commits. Strongest: ecosystem (Databricks), Unity Catalog, UniForm. Weakest: зависимость от Databricks для advanced features.
Apache IcebergCommunity-driven. Catalog + metadata tree. OCC через catalog atomic swap. Strongest: vendor-neutrality, REST catalog standard. Weakest: нет встроенных async services.
Apache HudiOriginally Uber. Timeline-based. OCC/NBCC. Strongest: incremental processing, async table services, NBCC. Weakest: heavier operational complexity, weaker Python ecosystem (read-only hudi-rs).

Практические рекомендации

TIP

Compaction: для MOR-таблиц с high-throughput ingestion используйте async compaction отдельным job’ом. Для low-throughput — inline с hoodie.compact.inline.max.delta.commits=5. Без compaction MOR read деградирует.

Cleaning: включайте hoodie.clean.automatic=true для production. Устанавливайте hoodie.cleaner.commits.retained исходя из требований time travel (30 = ~30 batch’ей). Не отключайте — storage будет расти бесконтрольно.

Clustering: запускайте для таблиц с point queries (WHERE region = ‘EU’). Сортировка по query-колонкам улучшает data skipping. Для scan-heavy workloads (full-table aggregation) clustering менее полезен.

XTable: используйте для миграции между форматами или для multi-engine доступа (Hudi write, Presto read через Iceberg). Incremental sync — раз в N commit’ов.

Итоги

  • Table Services — compaction (MOR: merge logs → base), cleaning (удаление старых FileSlice), clustering (реорганизация layout). Hudi — единственный формат с встроенным async scheduling.
  • Parquet Binary Copy (1.0): 10-15x ускорение compaction/clustering за счёт бинарного копирования row groups без десериализации.
  • XTable (incubating): конвертация метаданных Hudi ↔ Delta ↔ Iceberg без копирования данных. Аналог UniForm, но внешний и двунаправленный.
  • Движки: Spark (полная поддержка), Flink (streaming-first), Presto/Trino (read-only), hudi-rs (Python read-only).
  • Hudi 1.0: NBCC, secondary indexes, partial updates, LSM timeline, record index, binary copy — крупнейший релиз, выравнивающий Hudi с Delta Lake и Iceberg по feature parity.
  • Hudi сильнее всего в инкрементальной обработке (5 типов запросов, checkpoint ETL) и self-managing (async table services). Слабее в Python-экосистеме (read-only hudi-rs vs read+write deltalake/pyiceberg).

Проверьте понимание

Результат: 0 из 0
Прикладной
Вопрос 1 из 4. MOR-таблица не запускала compaction 3 дня. Streaming job делает deltacommit каждые 30 секунд. Какой симптом наиболее вероятен и какая стратегия compaction оптимальна для исправления?

Закончили урок?

Отметьте его как пройденный, чтобы отслеживать свой прогресс

Войдите чтобы оценить урок

Прогресс модуля
0 из 6