В предыдущих уроках мы разобрали внутреннюю архитектуру 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=truehoodie.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_VERSIONShoodie.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 решает ту же проблему, что UniForm в Delta Lake: multi-engine access без дублирования данных. Разница: UniForm встроен в Delta (автоматическая генерация Iceberg metadata при commit), а XTable — внешний инструмент, работающий с любым из трёх форматов как source.
Интеграция с движками
Hudi поддерживает Spark, Flink, Presto и Trino как основные движки. Начиная с версии 1.0, все четыре движка — равноправные:
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. Без десериализации. Описано выше в этом уроке.
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.
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, но внешний и двунаправленный.
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).
Доступ закрыт
Требуется вход
Для доступа к материалам курса необходимо войти через Telegram
Проверьте понимание
Результат: 0 из 0
Прикладной
Закончили урок?
Отметьте его как пройденный, чтобы отслеживать свой прогресс