Какая была цель проекта?
Цель проекта заключалась в создании централизованной batch-платформы для хранения и обработки данных о поведении пользователей, чтобы ускорить аналитику и помочь маркетингу и продукту принимать эффективные решения.
Кто были основные пользователи данных?
Основными пользователями были аналитики, продуктовые менеджеры и маркетологи. Аналитики использовали данные для построения отчетов и исследований, продукт — для оценки фичей, маркетинг — для анализа кампаний.
Какие типы данных обрабатывались?
Обрабатывались данные о кликах пользователей, заказах, сессиях и профилях пользователей из PostgreSQL, внешних API и S3.
Что за внешние API?
1) Партнёрские сервисы/поставщики данных: данные о промо-акциях, скидках, товарах.
2) Яндекс.Метрика
А какие именно типы данных это были? Json, csv?
Из PostgreSQL данные забирались через Spark JDBC (spark.read.jdbc).
Из внешних API данные получали по HTTP в формате JSON, предварительно сохраняли в staging-слой, после чего обрабатывали в Spark.
Из S3 данные читались напрямую с помощью Spark DataFrame API.
Какие объемы данных?
В среднем обрабатывалось несколько сотен гигабайт данных в день, общий объём хранилища — несколько терабайт.
А куда пропападали данные? Если за несколько дней-недель уже получаются терабайты?
Сырые данные сохранялись в Data Lake в Parquet.
Для старых данных использовались retention-политики: часть архивировалась, часть удалялась по TTL, чтобы не разрасталось хранилище.
Агрегированные данные сохранялись в ClickHouse.
А опиши весь пайплайн данных? Как выглядел high-level architecture пайплайна?
Почему выбрали batch, а не streaming?
Выбрали batch-подход, потому что он упрощал архитектуру, был дешевле в поддержке, а бизнес-требования были ориентированы на ежедневную отчетность, а не на real-time сценарии.
За какие части пайплайна ты отвечал лично?
Я отвечал за разработку и оптимизацию Spark задач на Python, создание и поддержку Data Lake и аналитических таблиц в ClickHouse, а также за построение пайплайнов в Apache Airflow для ежедневных batch-процессов. CI/CD сам не настраивал, но мой код проходил через CI/CD пайплайны.
Как организовывалось CI/CD, кто этим занимался
CI/CD я не настраивал с нуля, но мой код проходил через пайплайны, и я понимал, как они работают.
Чем еще занимался второй DE?
В принципе тем же, что и я без учета CI/CD
Сколько человек было в команде?
В команде было 3 человека: 2 Data Engineer, 1 аналитик
Был ли код-ревью? Кто утверждал архитектурные решения?
Да, был процесс код-ревью. Архитектурные решения обсуждались командой и утверждались старшим Data Engineer
Старший DE не считался в команде?
Старший Data Engineer не входил в ядро команды разработки, но утверждал архитектурные решения, делал код-ревью и помогал с оптимизацией пайплайнов.
Проект строился с нуля?
Большая часть платформы строилась с нуля: мы создавали Data Lake на HDFS, писали Spark ETL/ELT задачи и строили Airflow-пайплайны. Частично дорабатывались готовые аналитические таблицы ClickHouse
Какие решения ты принимал сам, а какие — нет?
Я самостоятельно принимал решения по Spark-задачам, оптимизации, структуре Data Lake и логике Airflow-DAG’ов. Архитектурные решения, влияющие на весь пайплайн, обсуждались командой.
Где все это было в gitlab?
Весь код хранился в GitLab, там же использовался встроенный CI/CD.
Почему ушел с проекта?
Основные задачи проекта были выполнены: Data Lake был построен, ETL/ELT пайплайны настроены, аналитические витрины созданы. После этого потребность в дополнительной работе Data Engineer на проекте была минимальна
Почему выбрали Spark, а не чистый Python / SQL?
Spark уже был стандартом в компании и хорошо подходил под объемы и HDFS.
Как выбирал количество партиций?
repartition или coalesce при необходимостиХорошо, как ты выберешь количество партиций, если данных 100 гб?
«Я ориентируюсь на 100–200 МБ данных на одну партицию. Для 100 ГБ данных это примерно 800–1000 партиций. При этом учитываю количество ядер кластера и после записи проверяю размер файлов, чтобы не было слишком маленьких. При необходимости использую repartition() или coalesce() для оптимизации.»
Разница между repartition() и `coalesce()
repartition(n) — всегда делает shuffle, создаёт n равномерно распределённых партицийcoalesce(n) — минимизирует shuffle, уменьшает количество партиций, если нужно только сжать данныеКакие форматы использовал (Parquet / ORC / CSV)?
В Data Lake использовался Parquet.
На этапе ingestion из API данные приходили в JSON.
CSV использовался редко — в основном для небольших внешних выгрузок или тестов.