Learning Platform
Глоссарий Troubleshooting
Урок 19.04 · 45 мин
Продвинутый
BenchmarkingDockerMetricsReportWrite ThroughputScan SpeedCompression RatioMerge LatencyPresentation

Бенчмаркинг и финальный отчёт

Третий и четвёртый deliverables: запуск бенчмарков и написание финального отчёта. Здесь вы проверяете свои решения из storage layer design на реальных данных — и объясняете результаты.

WARNING

Бенчмаркинг без методологии — маркетинг, а не инженерия. Прежде чем запускать тесты, перечитайте методологию бенчмаркинга из Модуля 17. Каждый benchmark должен иметь: hypothesis, controlled variables, measurement protocol, reproducibility guarantee.

Docker Lab: capstone-benchmarks

Capstone-benchmarks — Docker-based lab для сравнения форматов в контролируемой среде. Lab включает: data generator, write benchmarks, read benchmarks, merge benchmarks, compression benchmarks.

Docker Lab Architecture

docker compose up

docker-compose.yml запускает: (1) MinIO — S3-compatible object storage, (2) Spark — compute engine для read/write, (3) Benchmark runner — Python скрипт с PySpark, (4) Jupyter — для interactive exploration. Всё в Docker — reproducible на любой машине.

MinIO (S3)

MinIO — S3-compatible object storage. Эмулирует AWS S3 API. Все данные пишутся в MinIO buckets. Endpoint: http://minio:9000. Access/secret keys: minioadmin/minioadmin.

Spark 3.5

Apache Spark 3.5 с Iceberg, Delta Lake, Hudi support. PySpark client. Configured с Iceberg catalog (REST catalog на MinIO). Memory: 4 GB per executor (настраивается).

Benchmark Runner

Benchmark runner — Python + PySpark. Генерирует test data, запускает write/read/merge тесты, собирает метрики (time, bytes, rows), выводит отчёт. Configurable через benchmark_config.yaml.

Benchmark Results (JSON + Markdown)

Results: JSON + Markdown отчёт. Метрики: write throughput (rows/sec, MB/sec), read throughput (rows/sec, MB/sec), compression ratio, merge latency (sec per batch), file count, total size. Сравнение: Parquet vs ORC, Snappy vs Zstd, CoW vs MoR.

Запуск Lab

# Clone capstone-benchmarks lab
git clone https://github.com/your-org/capstone-benchmarks.git
cd capstone-benchmarks

# Start environment
docker compose up -d

# Run all benchmarks
docker compose exec spark ./run_benchmarks.sh

# View results
docker compose exec spark cat /results/report.md
NOTE

Если Docker lab недоступен, используйте локальный PySpark (без MinIO). Инструкции в README capstone-benchmarks. Ключевые бенчмарки можно запустить с local filesystem вместо S3. Результаты будут отличаться (local I/O vs S3 API), но relative comparison между форматами сохраняется.

Benchmarking Dimensions

Пять измерений бенчмарка — из методологии:

Benchmark Dimensions

Write Throughput

Write Throughput — скорость записи данных. Для bronze: append throughput (rows/sec при streaming ingestion). Для silver: merge throughput (rows/sec при CoW merge). Measurement: time to write N rows × row_size.
Что измеряемBronze: append 1M rows to Parquet/ORC on MinIO. Timer: от spark.write.start() до commit complete. Metrics: rows/sec, MB/sec (uncompressed), MB/sec (compressed). Vary: file format, compression codec, row group size.

Scan Speed

Scan Speed — скорость полного сканирования. Для gold: full table scan с aggregation. Measurement: time to SELECT COUNT(*), SUM(total), AVG(price) FROM table WHERE date BETWEEN ... GROUP BY region.
Что измеряемScan 10M rows: full scan (no filter), filtered scan (date range), aggregation (GROUP BY region). Timer: от spark.sql() до collect(). Metrics: rows/sec, GB scanned/sec. Vary: format, compression, sort order, partition layout.

Compression Ratio

Compression Ratio — сжатие данных. Для всех слоёв: uncompressed size / compressed size. Measurement: size on disk vs logical size. Vary: codec (Snappy, Zstd levels), encoding (dictionary, delta, RLE).
Что измеряемWrite 1M rows → measure: logical_size (sum of column values), physical_size (files on MinIO), ratio = logical / physical. Compare: Snappy vs Zstd 1/3/6/9 vs LZ4 vs uncompressed. Per-column analysis: which columns compress best?

Merge Latency

Merge Latency — время upsert операции. Для silver: MERGE INTO target USING source ON key = key. CoW: full file rewrite. MoR: delta append. Measurement: time per merge batch.
Что измеряемExisting table: 10M rows. Merge batch: 100K rows (10% update, 90% insert). Timer: MERGE INTO statement start to commit. Metrics: sec per batch, rows/sec, files rewritten (CoW) or deltas created (MoR). Compare: Iceberg CoW vs Hudi MoR.

Predicate Pushdown

Predicate Pushdown — эффективность фильтрации на уровне формата. Measurement: bytes read with/without pushdown. Effective pushdown = read only matching row groups / stripes.
Что измеряемQuery: SELECT * FROM table WHERE region = 'US' AND date = '2024-01-15'. Metrics: total bytes read vs data bytes returned. Pushdown effectiveness = 1 - (bytes_read / total_table_size). Vary: partition layout, sort order, statistics granularity.

Test Data: генерация

Lab генерирует данные, имитирующие наш e-commerce сценарий:

Test Data Schema
orders tableОсновная fact-таблица. 10M rows для full benchmark, 1M для quick tests. Колонки: order_id (BIGINT, PK), user_id (BIGINT, FK), status (STRING, 6 values), total (DECIMAL), region (STRING, 20 values), order_date (TIMESTAMP), items_count (INT), shipping_cost (DECIMAL).
clickstream tableEvent-таблица. 50M rows (высокий объём, как в production). Колонки: event_id (BIGINT), user_id (BIGINT), event_type (STRING, 10 values), page_url (STRING, high cardinality), session_id (STRING), timestamp (TIMESTAMP), device (STRING, 5 values).
products tableDimension-таблица. 100K rows (small). Колонки: product_id (BIGINT), name (STRING), category (STRING, 50 values), price (DECIMAL), description (STRING, long text), attributes (MAP, variable). Tests dictionary vs plain encoding.
users tableDimension-таблица. 1M rows (medium). Колонки: user_id (BIGINT), email (STRING, unique), region (STRING, 20 values), signup_date (TIMESTAMP), last_active (TIMESTAMP), preferences (STRING, JSON). Tests cardinality impact on encoding.

Controlled Variables

Каждый benchmark фиксирует все переменные кроме той, которую измеряем:

Controlled Variables Matrix
HardwareDocker container limits: 4 CPU cores, 8 GB RAM, SSD storage (or MinIO on SSD). Одинаковые limits для всех тестов. Spark: 1 executor, 4 cores, 4 GB memory. Warmup: 3 runs before measurement.
DataОдни и те же данные для всех format comparisons. Random seed: 42 (reproducible). Data distribution: realistic (zipf for user_id, uniform for region, skewed for status). Никогда не сравниваем разные данные.
QueryИдентичные SQL queries для всех format tests. Три типа: full scan, filtered scan, aggregation. Каждый query запускается 5 раз, берём median. Первый запуск — warmup (не считается).
EnvironmentDocker isolates от host variability. No other containers running. Network: docker bridge (no external calls). MinIO: same container, local I/O. Spark: deterministic parallelism (1 executor).
TIP

Если у вас медленная машина — уменьшите dataset size (1M вместо 10M). Relative comparison между форматами сохраняется при уменьшении данных. Absolute numbers изменятся, но ratios останутся стабильными. См. scaling considerations из Модуля 17.

Интерпретация результатов

Benchmark runner выдаёт JSON с метриками. Ваша задача — интерпретировать:

Как читать benchmark results

Raw Benchmark Results (JSON)

Raw results: JSON файл с метриками per test. Каждый test: {name, format, codec, rows, time_sec, bytes_written, bytes_read}. Множество тестов — нужна структура для анализа.
Структурирование
1. Group by DimensionГруппируем тесты по измерению: все write тесты вместе, все scan тесты вместе, все compression тесты вместе. Внутри каждой группы — сравнение format × codec × settings.
2. NormalizeАбсолютные числа зависят от hardware. Нормализуем: baseline format (Parquet + Snappy) = 1.0x. Все остальные — relative. Пример: ORC + Zstd = 0.8x write speed, 1.2x scan speed, 1.5x compression ratio.
3. Map to RequirementsПривязываем результаты к требованиям из design doc: 'Write throughput SLA: 10K events/sec'. Benchmark shows: Parquet+Snappy = 50K rows/sec → 5x margin → Да. ORC+Zstd = 30K rows/sec → 3x margin → Да but less headroom.
Анализ
Expected vs ActualСравниваем results с ожиданиями из design document. Если Zstd compression ratio = 4x (ожидали 4-5x) → consistent. Если Parquet scan = 2x faster than ORC (ожидали ~equal) → investigate. Discrepancy = learning opportunity.
SurprisesНеожиданные результаты — самое ценное. Пример: ORC bloom filter pruning для silver merge — ожидали 30% speedup, получили 5%. Почему? Потому что Iceberg partition pruning уже отсекает 95% data, bloom filter pruning on top даёт diminishing returns.

Типичные findings

На основе реальных бенчмарков e-commerce data (публичные отчёты, community benchmarks):

Типичные benchmark findings
Write: Parquet vs ORCParquet append: ~50-100K rows/sec (varies by schema). ORC append: ~40-80K rows/sec. Разница 10-20% в пользу Parquet для простого append. Причина: Parquet writer проще (нет bloom filter computation, нет stripe footer indexes). Для bronze (append-only) — Parquet marginal win.
Scan: Parquet vs ORCFull scan (no filter): Parquet and ORC within 5% of each other. Filtered scan with statistics pruning: Parquet ~equal to ORC. Filtered scan with bloom filters: ORC 10-30% faster for high-selectivity point queries. For analytics (low selectivity) — negligible difference.
Compression: Snappy vs ZstdSnappy: ratio ~2-3x, compress speed ~500 MB/s. Zstd-3: ratio ~3.5-4.5x, compress speed ~200 MB/s. Zstd-6: ratio ~4-5.5x, compress speed ~100 MB/s. Decompression: Snappy ~1500 MB/s, Zstd-3 ~1200 MB/s, Zstd-6 ~1000 MB/s. Surprise: decompress speed difference smaller than compress.
Merge: CoW vs MoRCoW (Iceberg): merge 100K into 10M rows = 15-30 sec. Files rewritten: 10-20%. MoR (Hudi): merge 100K = 3-8 sec. But: read with uncompacted deltas = 2x slower. After compaction: read speed equal. Trade-off: write speed vs read speed vs operational complexity.

Format Selection Report

Финальный deliverable — format selection report. Документ для “архитектурного комитета” (воображаемого):

Структура Format Selection Report
  1. Executive Summary
Executive Summary: 1 абзац. Что выбрали, почему, ключевые trade-offs. Аудитория: CTO/VP Engineering, которые прочитают только этот абзац. Пример: 'Parquet + Iceberg for all layers, Snappy/Zstd progression, CoW merge for silver — optimized for analytics read performance with acceptable write throughput.'
  1. Requirements
Requirements Recap: краткое повторение требований из capstone overview. Объём данных, throughput SLA, query SLA. Аудитория: инженеры, которые не читали full design doc.
  1. Design Decisions
Design Decisions: file format, table format, encoding, compression, partitioning per layer. Каждое решение: что, почему, какие альтернативы рассмотрели, какие trade-offs приняли.
  1. Benchmark Results
Benchmark Results: числа из Docker lab. Таблицы, графики. Comparison baseline. Expected vs actual. Surprises и их объяснения. Не raw dump — curated insights.
  1. Operational Plan
Operational Plan: compaction schedule, vacuum policy, monitoring alerts, schema change procedure, scaling path. Архитектура без ops плана — academic exercise, не production design.
  1. Risks & Mitigations
Risks & Mitigations: что может пойти не так? Vendor lock-in (Iceberg migration path). Schema breaking changes (new topic strategy). Data growth beyond projection (partition evolution). Each risk: probability, impact, mitigation.

Report Writing Guidelines

Guidelines для report
Да Do(1) Конкретные числа: 'Parquet write throughput: 65K rows/sec на test hardware' (не 'fast'). (2) Ссылки на курс: '[Модуль 02, Урок 02](/storage-formats/02-parquet/02-column-chunks/) объясняет row group structure'. (3) Trade-offs явно: 'CoW merge = 20 sec per batch (acceptable for 30 sec micro-batch), but read always optimized'. (4) Alternatives considered: 'ORC rejected because: multi-engine support weaker'.
Нет Don't(1) Vague claims: 'Parquet is better than ORC' (better how? for what workload?). (2) No numbers: 'Zstd compresses well' (how well? what ratio?). (3) No alternatives: 'We chose Iceberg' (why not Delta? why not Hudi?). (4) No ops plan: beautiful architecture without compaction → storage explosion in production.

Operational Plan

Архитектура — это 50% работы. Остальные 50% — операционный план:

Operational Plan для capstone-платформы
CompactionIceberg compaction: rewrite small files → larger files. Schedule: hourly для bronze (streaming creates many small files), daily для silver (after merge), weekly для gold (rarely changes). Tool: Spark 'CALL system.rewrite_data_files()'. Monitor: file count per partition — alert if > 1000.
Snapshot ExpiryIceberg snapshots enable time travel but accumulate. Expire policy: bronze = 7 days (debugging window), silver = 30 days (rollback window), gold = 90 days (audit trail). Tool: 'CALL system.expire_snapshots()'. Monitor: snapshot count — alert if > 100.
MonitoringKey metrics per layer: (1) Consumer lag (bronze ingestion), (2) Merge duration (silver), (3) Query p95 latency (gold), (4) Storage size per partition, (5) File count per partition, (6) Compaction job success/failure. Dashboard: Grafana + Prometheus.
Schema ChangesProcedure: (1) ALTER TABLE in PostgreSQL, (2) Debezium auto-registers new Avro schema, (3) Schema Registry validates BACKWARD compatibility, (4) Bronze consumer auto-adapts (nullable new fields), (5) Silver merge: add column to merge query, (6) Gold: update aggregation. Rollback: revert DDL + delete schema version.

Peer Review Checklist

Используйте этот checklist для self-review вашего capstone-проекта перед финальной “презентацией”:

Peer Review Checklist
Ingestion (Урок 02)[ ] Serialization формат выбран и обоснован. [ ] Schema Registry compatibility mode определён per subject. [ ] Consumer design: engine, trigger, error handling. [ ] Schema evolution procedure описана. [ ] Ссылки на M04/M05/M10.
Storage (Урок 03)[ ] File format per layer выбран и обоснован. [ ] Table format с CoW/MoR decision. [ ] Encoding per column type. [ ] Compression per layer с levels. [ ] Partitioning + sort order. [ ] Ссылки на M02/M03/M07-M09/M11-M14.
Benchmarks (Урок 04)[ ] All 5 dimensions measured. [ ] Controlled variables documented. [ ] Results normalized (baseline = 1.0x). [ ] Expected vs actual comparison. [ ] Surprises explained. [ ] Ссылки на M17.
Report[ ] Executive summary (1 абзац). [ ] Design decisions с trade-offs. [ ] Alternatives considered and rejected. [ ] Operational plan (compaction, monitoring, schema changes). [ ] Risks & mitigations. [ ] Нет vague claims без чисел.

Подведение итогов курса

Этот capstone-проект — не экзамен. Это инструмент: вы прошли путь от теории (побайтовый разбор форматов) через сравнение (decision framework) к практике (проектирование реальной системы). Знания из 17 модулей — от Parquet row groups до Iceberg partition evolution — теперь связаны в единую инженерную картину.

Путь через курс

M01-M07: Format Internals

Модули 01-07: основы форматов. Parquet, ORC, Avro, Protobuf, CSV/JSON, Arrow. Побайтовый разбор каждого формата. Результат: понимание внутреннего устройства.

M08-M10: Encoding, Compression, Schema

Модули 08-10: cross-cutting concerns. Encoding, compression, schema evolution. Применимо ко всем форматам. Результат: понимание оптимизаций и совместимости.

M11-M14: Table Formats

Модули 11-14: table formats. Delta Lake, Iceberg, Hudi, Paimon. ACID, transactions, metadata management. Результат: понимание lakehouse architecture.

M15-M16: Emerging Formats

Модули 15-16: emerging formats. Lance, Vortex, Nimble, F3. Next-generation approaches. Результат: awareness of future directions.

M17: Decision Framework

Модуль 17: decision framework. Workload archetypes, benchmarking methodology, table format selection, migration strategies, case studies. Результат: framework для принятия решений.

M18: Capstone (вы здесь)

Модуль 18: capstone. Применение всех знаний к реальному сценарию. Ingestion + storage + benchmarking + report. Результат: практический опыт end-to-end design.
TIP

Форматы хранения — активно развивающаяся область. Iceberg v3, Delta 4.0, новые codecs, Arrow-native execution — всё это меняется. Но фундаментальные принципы (columnar vs row, encoding, compression, schema evolution, ACID semantics) остаются. Курс дал вам framework для анализа любого нового формата — не только тех, что мы разобрали.

Capstone-проект завершён. Используйте glossary и troubleshooting как справочники при работе с форматами в production.

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

Результат: 0 из 0
Концептуальный
Вопрос 1 из 4. Docker lab для бенчмарков включает MinIO, Spark 3.5 и benchmark runner. Зачем использовать Docker вместо локального PySpark?

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

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

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

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