Data Lake архитектура¶
Зачем это DE?¶
Data Lake — центральное хранилище всех данных организации. Без правильной архитектуры он превращается в Data Swamp (болото). Медальонная архитектура, каталог, governance — то, что отличает рабочий lake от свалки файлов.
Data Lake vs Data Warehouse vs Lakehouse¶
| Параметр | Data Warehouse | Data Lake | Lakehouse |
|---|---|---|---|
| Формат | Структурированный (SQL) | Любой (raw файлы) | Структурированный + raw |
| Схема | Schema-on-Write | Schema-on-Read | Schema-on-Write (Delta/Iceberg) |
| Движок | PostgreSQL, Greenplum, Redshift | Spark, Presto, Athena | Spark + Delta Lake / Iceberg |
| Стоимость | $$$ (compute + storage связаны) | $ (S3 дёшево) | $ (S3 + compute по требованию) |
| ACID | ✅ | ❌ | ✅ (Delta/Iceberg) |
| Governance | Встроен | Нужен каталог | Встроен (Unity Catalog, Nessie) |
Медальонная архитектура (Bronze → Silver → Gold)¶
Text Only
┌─────────────────────────────────────────────────────────────┐
│ SOURCES │
│ API, Kafka, DB CDC, Files, Logs, IoT │
└──────────┬──────────┬──────────┬──────────┬─────────────────┘
↓ ↓ ↓ ↓
┌─────────────────────────────────────────────────────────────┐
│ BRONZE (Raw) │
│ • Данные as-is: JSON, CSV, Avro, DB dumps │
│ • Append-only, без изменений │
│ • Партиционирование по дате загрузки │
│ • Хранение: 90-365 дней │
│ • Формат: исходный или Parquet/Delta │
└──────────────────────────┬──────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ SILVER (Cleaned / Conformed) │
│ • Дедупликация, валидация, приведение типов │
│ • Единая схема (conform), JOIN обогащение │
│ • SCD Type 2 для измерений │
│ • Формат: Delta Lake / Iceberg (ACID!) │
│ • Хранение: 1-3 года │
└──────────────────────────┬──────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ GOLD (Business-level / Analytics) │
│ • Витрины для конкретных бизнес-задач │
│ • Агрегаты, KPI, ML-фичи │
│ • Star Schema для BI │
│ • Формат: Delta Lake / Parquet │
│ • Доступ: аналитики, BI-инструменты, ML │
└─────────────────────────────────────────────────────────────┘
Принципы каждого слоя¶
Bronze:
- Никаких трансформаций — только складываем
- Добавляем метаданные:
_loaded_at,_source,_batch_id - Если источник отдаёт JSON — сохраняем JSON
- Идемпотентность: повторная загрузка не создаёт дублей
Python
# Bronze: сохранить ответ API as-is
raw_data = requests.get("https://api.example.com/orders").json()
df = pd.DataFrame(raw_data)
df["_loaded_at"] = datetime.now()
df["_source"] = "api_orders"
df.to_parquet(f"s3://lake/bronze/orders/dt={today}/data.parquet")
Silver:
- Дедупликация (ROW_NUMBER по natural key)
- Приведение типов (string → int, timestamp parsing)
- Валидация (NULL-проверки, range checks)
- Обогащение (JOIN с справочниками)
Python
# Silver: очистка
df = pd.read_parquet("s3://lake/bronze/orders/")
df = df.drop_duplicates(subset=["order_id"], keep="last")
df["amount"] = pd.to_numeric(df["amount"], errors="coerce")
df = df.dropna(subset=["order_id", "amount"])
df.to_parquet(f"s3://lake/silver/orders/dt={today}/data.parquet")
Gold:
- Агрегаты по бизнес-логике
- Star Schema для BI
- Предрассчитанные метрики
Python
# Gold: витрина выручки
revenue = (df.groupby(["date", "region"])
.agg(orders=("order_id", "count"),
revenue=("amount", "sum"))
.reset_index())
revenue.to_parquet("s3://lake/gold/daily_revenue/data.parquet")
Schema-on-Read vs Schema-on-Write¶
Schema-on-Read (Data Lake)¶
Данные складываются без схемы. Схема применяется при чтении:
Python
# Читаем CSV — схему определяем при чтении
df = spark.read.csv("s3://lake/raw/messy.csv",
header=True, inferSchema=True)
# Проблема: inferSchema может ошибиться (string вместо int)
Плюсы: гибкость, быстрая загрузка Минусы: "мусор на входе — мусор на выходе", каждый потребитель парсит по-своему
Schema-on-Write (DWH, Lakehouse)¶
Схема определяется при записи:
Python
# Delta Lake — MERGE с проверкой схемы
target.alias("t").merge(
source.alias("s"),
"t.order_id = s.order_id"
).whenMatchedUpdate(...).whenNotMatchedInsert(...).execute()
# Ошибка если схемы source и target не совпадают
Плюсы: данные гарантированно чистые Минусы: нужна предварительная подготовка
Каталог данных¶
Без каталога Data Lake превращается в болото: никто не знает, что лежит в s3://lake/old_data_v2_final_FINAL/.
Что содержит каталог¶
- Схема — столбцы, типы, описания
- Расположение — путь в S3
- Владелец — кто отвечает за данные
- Lineage — откуда пришли, куда уходят
- Качество — SLA, freshness, тесты
- Доступ — кому разрешено читать/писать
Инструменты¶
| Инструмент | Тип | Особенности |
|---|---|---|
| Hive Metastore | Технический каталог | Стандарт для Spark/Presto/Trino |
| AWS Glue Catalog | Managed Hive | Авто-discovery через Crawlers |
| DataHub | Data Discovery | Lineage, governance, search |
| Unity Catalog | Databricks | Governance + RBAC + lineage |
| Apache Nessie | Git-like каталог | Ветвление данных как Git-ветки |
Антипаттерны Data Lake¶
1. Data Swamp — нет организации¶
Решение: медальонная архитектура + naming convention + каталог.
2. Small Files Problem¶
Text Only
❌ 100,000 файлов по 1 KB = медленно (overhead на открытие каждого)
✅ Компактификация: объединять мелкие файлы в ~128-256 MB
Python
# Компактификация через Spark
df = spark.read.parquet("s3://lake/bronze/events/dt=2025-01-15/")
df.coalesce(4).write.parquet("s3://lake/bronze/events_compacted/dt=2025-01-15/")
3. Нет партиционирования¶
Text Only
❌ s3://lake/orders/all_data.parquet # 100 GB, читаем целиком
✅ s3://lake/orders/year=2025/month=01/ # читаем только нужный месяц
4. Over-partitioning¶
Text Only
❌ Партиции по customer_id → миллион партиций → миллион мелких файлов
✅ Партиционировать по дате (year/month/day) — 365 партиций в год
5. Нет ACID → потеря данных¶
Text Only
❌ Parquet: запись прервалась на середине → битый файл
✅ Delta Lake: ACID-транзакции, atomicity, rollback
Что запомнить¶
| Концепция | Ключевое | Пример |
|---|---|---|
| Bronze | Raw, as-is, append-only | API-ответы в Parquet |
| Silver | Cleaned, conformed, deduplicated | JOIN + дедупликация |
| Gold | Business metrics, Star Schema | Витрина выручки |
| Schema-on-Read | Гибкость, но мусор | CSV в Data Lake |
| Schema-on-Write | Надёжность, но жёсткость | Delta Lake MERGE |
| Каталог | Знание о данных | DataHub, Hive Metastore |
| Партиционирование | Быстрый доступ | year/month/day |