Learning Platform
Глоссарий
Troubleshooting

Решение проблем System Design для Data Engineer

Частые ошибки проектирования data-платформ — симптомы, причины и пошаговые решения.

Область

Тип ошибки

Показано 20 из 20 ошибок

Симптомы

  • Дублирование бизнес-логики между batch и speed слоями
  • Расхождения результатов между batch-вычислениями и realtime-вычислениями
  • Высокие затраты на поддержку двух параллельных pipeline

Причина

Выбор Lambda Architecture по умолчанию без анализа реальных требований к латентности. Если задержка до нескольких минут допустима, Kappa Architecture с единым streaming-pipeline значительно проще в поддержке.

Решение

  1. Оцените реальные SLA по латентности: если >1 мин допустимо, Kappa достаточно
  2. Если Lambda необходима, вынесите общую бизнес-логику в shared-библиотеку
  3. Используйте serving layer (Druid, ClickHouse) для объединения batch и speed результатов
  4. Рассмотрите Medallion Architecture как альтернативу с чёткими слоями

Симптомы

  • Ошибка в одном источнике данных блокирует весь pipeline
  • Невозможно перезапустить обработку отдельного источника без перезапуска всего процесса
  • Время восстановления после сбоя измеряется часами

Причина

Все источники данных обрабатываются в одном монолитном процессе без разделения на независимые единицы. Отсутствует fault isolation — сбой любого этапа каскадирует на весь pipeline.

Решение

  1. Декомпозируйте pipeline на независимые DAG-задачи по источникам
  2. Реализуйте idempotent-операции для безопасного перезапуска отдельных этапов
  3. Добавьте circuit breaker между этапами pipeline
  4. Используйте оркестратор (Airflow, Dagster) с retry-политиками на уровне задач

Связанные уроки:

Симптомы

  • Деградация производительности production-приложения во время аналитических запросов
  • Блокировки таблиц при длительных SELECT-запросах
  • Жалобы пользователей на медленный сервис в часы работы ETL

Причина

Аналитические запросы выполняются напрямую к production базе вместо создания отдельного аналитического хранилища. OLTP-база оптимизирована для транзакций, не для сканирования больших объёмов данных.

Решение

  1. Настройте CDC (Debezium, DMS) для репликации данных в аналитическое хранилище
  2. Создайте read-replica для аналитических запросов как временное решение
  3. Спроектируйте отдельный OLAP-слой (DWH или Lakehouse) для аналитики
  4. Определите SLA для свежести данных — часто near-realtime через CDC достаточно

Связанные уроки:

Симптомы

  • Изменение схемы в одном сервисе ломает downstream-потребителей
  • Невозможно добавить нового consumer без модификации producer
  • Каскадные сбои при обновлении одного из компонентов

Причина

Отсутствие промежуточного слоя абстракции между производителями и потребителями данных. Producer напрямую пишет в таблицу consumer или использует point-to-point интеграцию без event bus.

Решение

  1. Внедрите event-driven архитектуру с Kafka/Pulsar как промежуточным слоем
  2. Определите data contracts (schema registry) между producer и consumer
  3. Используйте schema evolution (Avro, Protobuf) для backward-compatible изменений
  4. Реализуйте паттерн Reverse ETL для обратной доставки данных в сервисы

Связанные уроки:

Симптомы

  • Время выполнения pipeline растёт линейно с ростом данных
  • Высокие затраты на compute — каждый запуск перечитывает весь объём
  • Окно обработки (batch window) приближается к интервалу запуска

Причина

Все данные перечитываются и перезаписываются при каждом запуске ETL, потому что не реализован механизм отслеживания изменений (watermark, CDC timestamp, audit columns).

Решение

  1. Реализуйте incremental load по колонке updated_at или CDC timestamp
  2. Используйте MERGE (upsert) вместо полной перезаписи таблицы
  3. Настройте partitioning по дате для обработки только новых партиций
  4. Рассмотрите CDC как источник инкрементальных изменений

Связанные уроки:

Симптомы

  • Запросы к таблице выполняются медленнее, чем к неразбитой версии
  • File listing операции занимают минуты в S3/GCS/ADLS
  • Spark/Trino показывают Planning Time > Execution Time

Причина

Избыточное партиционирование по колонкам с высокой кардинальностью (user_id, timestamp) создаёт тысячи директорий с файлами в несколько килобайт. Overhead метаданных превышает выигрыш от partition pruning.

Решение

  1. Партиционируйте только по колонкам с низкой кардинальностью (дата, регион)
  2. Целевой размер файла: 128 MB – 1 GB для Parquet/ORC
  3. Используйте compaction (Iceberg, Delta Lake) для объединения мелких файлов
  4. Замените партиционирование на Z-order/Hilbert clustering для multi-dimensional фильтрации

Связанные уроки:

Симптомы

  • Bronze-слой хранит данные в Parquet, теряя оригинальный формат при сбоях
  • BI-инструменты медленно читают данные из Raw-зоны
  • Невозможно воспроизвести трансформацию из-за потери исходных данных

Причина

Все слои Data Lake (Raw, Curated, Serving) используют одинаковый формат без учёта требований каждого слоя. Raw-данные должны сохранять оригинальный формат для аудита, а serving-слой — оптимизированный для чтения.

Решение

  1. Bronze/Raw: сохраняйте оригинальный формат (JSON, CSV, Avro) as-is
  2. Silver/Curated: конвертируйте в колоночный формат (Parquet, ORC) с компрессией
  3. Gold/Serving: используйте materialized views или агрегированные таблицы
  4. Внедрите table format (Iceberg, Delta) для ACID-транзакций и time travel

Связанные уроки:

Симптомы

  • Агрегаты в realtime-дашбордах занижают реальные значения
  • Данные от мобильных устройств теряются при восстановлении связи
  • Расхождения между streaming-результатами и batch-пересчётом

Причина

Streaming-pipeline использует processing time вместо event time и не настроены watermarks. Данные, поступившие с задержкой (out-of-order events), отбрасываются или попадают в неправильное окно.

Решение

  1. Переключитесь на event time processing с watermarks
  2. Настройте allowed lateness для допуска опоздавших событий
  3. Реализуйте side output (dead letter) для событий за пределами watermark
  4. Используйте session windows вместо fixed windows для нерегулярного трафика

Связанные уроки:

Симптомы

  • Pipeline останавливается при получении невалидного сообщения
  • Poison pill — одно сообщение блокирует обработку всей партиции
  • Потеря данных при skip невалидных записей без логирования

Причина

Streaming consumer не обрабатывает ошибки десериализации и бизнес-валидации. Сбой на одном сообщении вызывает бесконечный retry или молчаливый skip без сохранения проблемного сообщения.

Решение

  1. Реализуйте Dead Letter Queue (DLQ) — отдельный topic для ошибочных сообщений
  2. Добавьте metadata к DLQ-записям: original topic, partition, offset, error reason
  3. Настройте alerting при росте DLQ выше порога
  4. Создайте инструмент для replay обработанных DLQ-сообщений после исправления

Симптомы

  • Consumer lag растёт неограниченно при всплесках нагрузки
  • OOM на consumer при накоплении буфера необработанных сообщений
  • Каскадный отказ downstream-сервисов при burst-записи

Причина

Pipeline не ограничивает скорость потребления при превышении пропускной способности обработки. Отсутствуют механизмы противодавления между источником и обработчиком.

Решение

  1. Настройте max.poll.records и fetch.max.bytes в Kafka consumer
  2. Используйте встроенный backpressure Flink (credit-based flow control)
  3. Реализуйте rate limiting на уровне sink-коннектора
  4. Мониторьте consumer lag как ключевую метрику здоровья pipeline

Связанные уроки:

Симптомы

  • Медленные MERGE/UPDATE операции в fact-таблице
  • Lock contention при параллельных обновлениях dimension-таблиц
  • Рост latency аналитических запросов из-за частых перестроений индексов

Причина

Классическая Star Schema оптимизирована для append-only загрузки и read-heavy аналитики. При частых обновлениях (>10K/мин) MERGE-операции на больших fact-таблицах становятся узким местом.

Решение

  1. Используйте SCD Type 2 для dimension-таблиц вместо UPDATE
  2. Рассмотрите append-only модель с версионированием записей
  3. Для near-realtime: используйте materialized views поверх streaming-слоя
  4. Оцените Data Vault как альтернативу для часто меняющихся источников

Связанные уроки:

Симптомы

  • Бизнес-логика размазана по десяткам SQL-запросов без единого источника правды
  • Дублирование трансформаций в разных отчётах с разными результатами
  • Невозможно отследить происхождение (lineage) метрики

Причина

Отсутствие архитектуры слоёв данных. Все трансформации выполняются в одном шаге — от raw-данных до финальных отчётов. Нет промежуточных staging-таблиц и переиспользуемых data marts.

Решение

  1. Внедрите Medallion (Bronze → Silver → Gold) или Staging → Marts архитектуру
  2. Определите single source of truth для каждой бизнес-метрики в marts-слое
  3. Используйте dbt или аналог для управления зависимостями между моделями
  4. Документируйте data lineage на уровне каждой таблицы

Связанные уроки:

Симптомы

  • Добавление нового поля в источнике ломает downstream-pipeline
  • Потребители данных не могут читать старые партиции после изменения схемы
  • Ручная миграция данных при каждом изменении формата

Причина

Не определена стратегия развития схемы данных. Изменения схемы (добавление, удаление, переименование полей) не управляются централизованно и не поддерживают backward/forward compatibility.

Решение

  1. Используйте schema registry (Confluent, AWS Glue) для версионирования схем
  2. Определите compatibility mode: BACKWARD для consumer, FORWARD для producer
  3. Выберите формат с встроенной schema evolution: Avro, Protobuf (не JSON, CSV)
  4. Внедрите data contracts с автоматической валидацией при CI/CD

Симптомы

  • Тихие сбои — pipeline работает, но выдаёт некорректные данные
  • Обнаружение проблемы через дни или недели после изменения в источнике
  • Нет ответственного за качество данных между командами

Причина

Между командой-производителем данных и командой-потребителем нет формального соглашения о схеме, SLA по свежести и полноте данных. Изменения в upstream-системе никому не сообщаются.

Решение

  1. Определите data contract: schema, SLA (freshness, completeness), ownership
  2. Автоматизируйте валидацию контрактов в CI/CD pipeline
  3. Настройте alerting при нарушении контракта (schema drift, SLA breach)
  4. Внедрите инструмент управления контрактами (Soda, Great Expectations, Monte Carlo)

Симптомы

  • Аналитики обнаруживают аномалии в отчётах раньше, чем data-инженеры
  • NULL-значения и дубликаты проникают в serving-слой незамеченными
  • Невозможно определить, на каком этапе pipeline данные повредились

Причина

Data quality проверки отсутствуют или выполняются только на финальном этапе. Между слоями (Raw → Curated → Serving) нет point-of-check валидации — ошибки обнаруживаются слишком поздно.

Решение

  1. Добавьте DQ-проверки на границе каждого слоя (freshness, completeness, uniqueness)
  2. Используйте profiling для установки baseline-метрик и detection anomalий
  3. Настройте circuit breaker: блокируйте загрузку в serving-слой при DQ-failure
  4. Реализуйте data observability dashboard с историей DQ-метрик

Симптомы

  • Scheduler не справляется с количеством DAG и задач
  • Задачи ожидают в очереди часами из-за ограниченных worker-слотов
  • Единая точка отказа — потеря scheduler блокирует все pipeline

Причина

Оркестратор (Airflow, Prefect) развёрнут на одном сервере без горизонтального масштабирования. При росте количества DAG и задач single-node становится bottleneck.

Решение

  1. Переведите Airflow на CeleryExecutor или KubernetesExecutor для горизонтального масштабирования
  2. Настройте HA для scheduler: Airflow 2.x поддерживает multiple schedulers
  3. Разделите DAG по доменам между несколькими Airflow-инстансами
  4. Рассмотрите serverless-оркестраторы (Dagster Cloud, Prefect Cloud) для автомасштабирования

Симптомы

  • Downstream DAG запускается до завершения записи данных upstream
  • Race condition при параллельных записях в одну директорию
  • Пропуск запуска при несовпадении расписаний upstream и downstream

Причина

Зависимости между DAG реализованы через cron-расписание или проверку наличия файла, а не через событийную модель. Upstream и downstream DAG не знают друг о друге и полагаются на timing.

Решение

  1. Используйте data-aware scheduling: Airflow Datasets, Dagster assets
  2. Реализуйте event-driven триггеры: S3 event → Lambda → DAG trigger
  3. Добавьте sensor с таймаутом как fallback для проверки готовности данных
  4. Определите _SUCCESS маркеры (файлы-флаги) как явный сигнал завершения записи

Связанные уроки:

Симптомы

  • Невозможно определить impact analysis при изменении таблицы-источника
  • Дублирование таблиц — команды создают свои копии, не зная о существующих
  • Аудит и compliance невозможны — нет информации о происхождении данных

Причина

Метаданные и происхождение данных (lineage) не отслеживаются централизованно. Каждая команда работает изолированно, не имея общего каталога доступных данных и их зависимостей.

Решение

  1. Внедрите data catalog (DataHub, OpenMetadata, Amundsen) для регистрации всех datasets
  2. Настройте автоматический сбор lineage из Spark, Airflow, dbt
  3. Определите data stewards — ответственных за каждый dataset
  4. Реализуйте impact analysis перед любым изменением схемы

Связанные уроки:

Симптомы

  • Неожиданный рост облачного счёта на 200-500%
  • Забытые dev/staging кластеры работают 24/7
  • Нет visibility — невозможно определить, какой pipeline потребляет больше всего ресурсов

Причина

Отсутствие автоматизации cost management: нет бюджетов, алертов, auto-shutdown для non-production ресурсов. Стоимость инфраструктуры не привязана к конкретным pipeline и командам.

Решение

  1. Настройте cloud budget alerts на 50%, 80%, 100% от лимита
  2. Реализуйте tagging strategy: каждый ресурс привязан к команде и pipeline
  3. Автоматизируйте shutdown dev/staging кластеров в нерабочее время
  4. Внедрите FinOps-отчёт: cost per pipeline run как метрику эффективности

Связанные уроки:

Симптомы

  • ML-команда дублирует ETL-pipeline для подготовки features
  • Training-serving skew — features вычисляются по-разному в train и inference
  • Невозможно переиспользовать features между разными ML-моделями

Причина

Feature Store развёрнут изолированно от основной data-платформы. ML-инженеры строят собственные pipeline вместо использования curated-данных из DWH/Lakehouse.

Решение

  1. Интегрируйте Feature Store с существующим data lake/warehouse как source of truth
  2. Используйте единый compute (Spark, Flink) для batch и online features
  3. Реализуйте feature registry с lineage до исходных таблиц
  4. Стандартизируйте feature computation: одна кодовая база для train и serve

Связанные уроки: