Data Management + Optimization
В предыдущих уроках мы разобрали архитектуру хранения Paimon: LSM-деревья (Урок 01), merge engine’ы (Урок 02), changelog producer (Урок 03) и bucket/partition design (Урок 04). Теперь — как управлять данными в production: компакция, deletion vectors, z-order, data skipping и snapshot lifecycle.
Компакция: управление LSM-деревом
Компакция — фундаментальная операция LSM-дерева: объединение sorted runs для уменьшения read amplification. Paimon запускает компакцию автоматически, но параметры критически влияют на производительность.
5 sorted runs Read: merge 5 потоков
До компакции: 5 sorted runs в бакете. Каждый sorted run — результат одного flush из MemTable. Point lookup требует проверки всех 5 runs (merge на чтении). Range scan мержит 5 потоков.1-2 sorted runs Read: merge 1-2 потока
После компакции: sorted runs объединены в меньшее количество (или один). Read performance улучшается — меньше потоков для merge. Данные физически перезаписаны в новые SST-файлы (Parquet).Три ключевых параметра компакции
Стратегии компакции
Paimon поддерживает две стратегии компакции (подробнее в Уроке 01):
Для стриминговых таблиц с changelog-producer = lookup или full-compaction, компакция играет двойную роль: уменьшает read amplification И генерирует changelog. Параметр full-compaction.delta-commits контролирует, как часто запускается full compaction для генерации changelog (подробнее в Уроке 03).
Deletion Vectors для Append-Only таблиц
Primary key таблицы обрабатывают удаления через merge engine (tombstone marker в LSM-дереве). Но append-only таблицы (без primary key) не имеют merge engine. Как удалять строки?
Read: data file + DV bitmap Skip строки: bitmap.contains(pos) → O(1) Результат: 999,900 строк
При scan: Paimon читает data file + deletion vector. Для каждой строки: if bitmap.contains(row_position) → skip. O(1) check per row. 999,900 строк возвращаются, 100 — пропущены. Нет перезаписи data file.Deletion vectors в Paimon аналогичны deletion vectors в Delta Lake (DVR — Deletion Vector Reader) и Iceberg V3 (Puffin-based DVs). Все три формата используют Roaring Bitmap для compact representation позиций. Разница — в формате хранения: Paimon хранит DV как отдельный файл рядом с data file, Delta — в _delta_log, Iceberg — в Puffin blob.
Компакция с deletion vectors: периодически Paimon объединяет data file + deletion vector в новый файл без удалённых строк. Это уменьшает overhead при чтении (не нужно проверять bitmap) и освобождает storage.
Z-Order Сортировка
По умолчанию данные в SST-файлах Paimon отсортированы по primary key (для primary key таблиц) или по порядку записи (для append-only). Z-order сортировка меняет порядок данных для улучшения data skipping при запросах по нескольким колонкам.
-- Z-Order rewrite для таблицы events
-- Paimon перезаписывает data files с z-order сортировкой
ALTER TABLE events SET ('zorder.columns' = 'region,category');
-- Или через dedicated action:
CALL sys.compact('default.events', 'zorder', 'region,category');
Z-order — дорогая операция: полная перезапись данных с новым порядком. Запускайте как batch-задачу в low-traffic окне. Z-order не совместим с primary key сортировкой — для primary key таблиц z-order применяется при компакции к значениям (value columns), но ключи остаются отсортированными для merge.
Data Skipping: Min/Max + Bloom Filter
Data skipping — механизм пропуска файлов и row group’ов при чтении. Paimon поддерживает два уровня:
- Partition pruning
- Bucket pruning (PK hash)
- Min/Max file-level
- Bloom filter per-column
- Row-group level (Parquet)
Включение Bloom filter для конкретных колонок:
-- Включить bloom filter для колонки user_id
ALTER TABLE events SET (
'fields.user_id.bloom-filter.enabled' = 'true',
'fields.user_id.bloom-filter.fpp' = '0.01' -- false positive rate 1%
);
Bloom filter эффективен для high-cardinality колонок с equality-запросами: user_id, order_id, device_id. Для low-cardinality (status, region) min/max statistics достаточно. Для range-запросов (amount BETWEEN 100 AND 200) bloom filter бесполезен — используйте z-order.
Tag Management: именованные snapshot’ы
Snapshot в Paimon — это состояние таблицы в определённый момент: набор manifest’ов → набор SST-файлов → данные. Snapshot’ы создаются автоматически при каждом commit. Tag — это именованный snapshot, защищённый от автоматического удаления.
Каждый commit → snapshot Streaming: ~720 snapshot/day
Каждый commit (write, compaction) создаёт новый snapshot. При streaming ingestion: snapshot каждые 1-2 минуты. За сутки: ~720-1440 snapshot'ов. Без lifecycle management — storage растёт бесконечно.Retain: последние N snapshot’ов snapshot.num-retained.min = 10 snapshot.time-retained = 1h
Snapshot retention: Paimon хранит последние N snapshot'ов (snapshot.num-retained.min / max). Старые snapshot'ы expire — их metadata удаляется, data файлы, не referenced другими snapshot'ами — GC'd. Параметр: snapshot.time-retained (по времени).Expire: metadata удалена Orphan files → GC
Expired snapshot'ы: metadata удалена. Data файлы: orphan если ни один оставшийся snapshot не ссылается. Orphan files GC — отдельная процедура (аналог Iceberg expire_snapshots + remove_orphan_files).Tag — это закладка на snapshot, которую expire не тронет:
-- Создать тег вручную
CALL sys.create_tag('default.orders', 'daily-2025-03-27', 720);
-- Автоматические теги: ежедневно
ALTER TABLE orders SET (
'tag.automatic-creation' = 'process-time',
'tag.creation-period' = 'daily',
'tag.num-retained-max' = '30' -- хранить последние 30 дней
);
-- Удалить тег
CALL sys.delete_tag('default.orders', 'daily-2025-03-27');
Time Travel: чтение исторического состояния
Time travel в Paimon работает через snapshot ID или tag:
Сравнение с другими форматами:
Snapshot Lifecycle: полная картина
- Commit → Snapshot
- Active Window Retention: N snapshot’ов
- Expire Metadata удалена
- GC: orphan files Storage освобождён
Подводим итоги
Data management в Paimon — это баланс между write performance (минимальная компакция), read performance (максимальный data skipping) и storage cost (snapshot lifecycle + GC):
-
Компакция — настраивайте trigger threshold под workload: стриминг (частая, мелкая) vs batch (редкая, крупная). Universal compaction для read-heavy, sorted-run для write-heavy.
-
Deletion vectors — для append-only таблиц: DELETE без перезаписи файлов. Roaring bitmap, O(1) check per row. Периодическая компакция merge’ит DV в data files.
-
Z-order — для аналитических запросов по нескольким колонкам. Дорогая одноразовая перезапись, но кардинальное улучшение data skipping.
-
Data skipping — многоуровневый: partition → bucket → min/max → bloom filter → row group. Bloom filter для high-cardinality equality, z-order для multi-column ranges.
-
Snapshot lifecycle — expire по count или time, tag для protection, auto-tag для расписания. GC для orphan files.
В следующем уроке мы рассмотрим экосистему Paimon: интеграции с Flink, Spark, OLAP-движками, Iceberg compatibility layer и сравнение с Hudi, Delta Lake и Iceberg.