diff --git a/airflow-greenplum/.env.example b/airflow-greenplum/.env.example index a487abf..ad2f0e0 100644 --- a/airflow-greenplum/.env.example +++ b/airflow-greenplum/.env.example @@ -1,22 +1,19 @@ -# ==== Compose Environment (.env) ==== -# Airflow metadata DB (Postgres) +# Airflow Configuration +AIRFLOW_USER=admin +AIRFLOW_PASSWORD=admin + +# PostgreSQL (Airflow metadata) PG_USER=airflow PG_PASSWORD=airflow PG_DB=airflow -# Greenplum access from Airflow +# Greenplum Configuration +GP_USER=gpadmin +GP_PASSWORD=gpadmin +GP_DB=gpadmin GP_HOST=greenplum GP_PORT=5432 -GP_DB=gpadmin -GP_USER=gpadmin -# В большинстве демо-образов TCP доступ настроен без пароля (trust). -# Если потребуется пароль, задай его здесь: -GP_PASSWORD= -# Kafka +# Kafka Configuration KAFKA_BOOTSTRAP=kafka:9092 KAFKA_TOPIC=orders - -# Airflow admin -AIRFLOW_USER=admin -AIRFLOW_PASSWORD=admin diff --git a/airflow-greenplum/Makefile b/airflow-greenplum/Makefile index 6624e72..f1f57bf 100644 --- a/airflow-greenplum/Makefile +++ b/airflow-greenplum/Makefile @@ -13,7 +13,7 @@ logs: docker compose -f docker-compose.yml logs -f airflow-webserver airflow-scheduler gp-psql: - docker compose -f docker-compose.yml exec greenplum bash -lc "su - gpadmin -c 'psql -p 5432 -d gpadmin'" + docker compose -f docker-compose.yml exec greenplum bash -c "su - gpadmin -c '/usr/local/greenplum-db/bin/psql -p 5432 -d gpadmin'" ddl-gp: - docker compose -f docker-compose.yml exec greenplum bash -lc "su - gpadmin -c \"psql -d gpadmin -f /sql/ddl_gp.sql\"" + docker compose -f docker-compose.yml exec greenplum bash -c "su - gpadmin -c '/usr/local/greenplum-db/bin/psql -d gpadmin -f /sql/ddl_gp.sql'" diff --git a/airflow-greenplum/README.md b/airflow-greenplum/README.md index d332ee3..ed8b10b 100644 --- a/airflow-greenplum/README.md +++ b/airflow-greenplum/README.md @@ -6,22 +6,28 @@ Airflow по‑прежнему использует **Postgres** только как metadata DB (это стандартная и простая схема). ## Что внутри -- **Greenplum** (single node) — `datagrip/greenplum:6.8` (локальный стенд для разработки). +- **Greenplum** (single node) — `woblerr/greenplum:6.27.1` (локальный стенд для разработки). - **Kafka (KRaft, без Zookeeper)** — генерация событий. - **Airflow (2.9)** — оркестрация пайплайна, metadata в Postgres. - **DAG** `kafka_to_greenplum.py` — генерирует данные → пишет в Kafka → читает и грузит в Greenplum. - **DDL** `sql/ddl_gp.sql` — создаёт таблицу `orders` с распределением по `order_id`. -> Примечание по версиям и надёжности: образы Greenplum в публичном Docker Hub — комьюнити/сторонние. Я выбрал `datagrip/greenplum:6.8` как популярный и поддерживаемый для локальной разработки. Для продакшен‑подобных тестов зафиксируй digest (SHA256) конкретного тега на Docker Hub и/или собери образ самостоятельно. См. раздел «Пинning и альтернативы» ниже. +> Примечание по версиям и надёжности: используется образ `woblerr/greenplum:6.27.1` с поддержкой переменных окружения и fallback значениями. Для продакшен‑подобных тестов зафиксируй digest (SHA256) конкретного тега на Docker Hub. ## Быстрый старт Установим make под Вашу операционную систему ```bash sudo apt install -y make ``` -Запустим приложение + +Настроим переменные окружения ```bash cp .env.example .env +# При необходимости отредактируйте .env для ваших настроек +``` + +Запустим приложение +```bash make up && make airflow-init make logs # ждем "Listening at: http://0.0.0.0:8080" ``` @@ -30,23 +36,45 @@ make logs # ждем "Listening at: http://0.0.0.0:8080" ### Проверка загрузки ```bash -make gp-psql # войти в psql к Greenplum --- внутри psql: +# Подключение к Greenplum через внешний psql клиент +psql -h localhost -p 5432 -U gpadmin -d gpadmin + +# Или через Docker (используя make команду) +make gp-psql + +# Или напрямую через Docker +docker compose -f docker-compose.yml exec greenplum bash -c "su - gpadmin -c '/usr/local/greenplum-db/bin/psql -p 5432 -d gpadmin'" + +# Внутри psql: \dt SELECT count(*) FROM public.orders; ``` ## Файлы -- `docker-compose.gp.yml` — сервисы Greenplum + Kafka + Airflow + Postgres (metadata). -- `.env.example` — переменные окружения. +- `docker-compose.yml` — сервисы Greenplum + Kafka + Airflow + Postgres (metadata). +- `.env.example` — шаблон переменных окружения. +- `.env` — переменные окружения (создается из .env.example). - `airflow/dags/kafka_to_greenplum.py` — сам DAG. - `sql/ddl_gp.sql` — DDL таблицы в Greenplum. - `Makefile` — обёртки команд (`up`, `down`, `airflow-init`, `gp-psql`, `ddl-gp`). +## Конфигурация через переменные окружения +Все настройки Greenplum передаются через переменные окружения в файле `.env` с fallback значениями: + +- `GP_USER` — пользователь Greenplum (по умолчанию: gpadmin) +- `GP_PASSWORD` — пароль пользователя (по умолчанию: gpadmin) +- `GP_DB` — база данных (по умолчанию: gpadmin) +- `GP_PORT` — порт для подключения (по умолчанию: 5432) + +Образ `woblerr/greenplum:6.27.1` использует переменные: +- `GREENPLUM_USER` (маппится на `GP_USER`) +- `GREENPLUM_PASSWORD` (маппится на `GP_PASSWORD`) +- `GREENPLUM_DATABASE_NAME` (маппится на `GP_DB`) + ## Пинning и альтернативы -- Зафиксируй digest образа `datagrip/greenplum:6.8` (Docker Hub → Tag → «Copy digest») и замени тег на `@sha256:...` в `docker-compose.gp.yml`. -- Альтернативы: репозиторий `woblerr/docker-greenplum` позволяет **собрать свой образ** для GPDB 6/7 (подойдёт, если нужен полный контроль и повторяемость сборки). -- Особенность GPDB 6: в нём **нет** `INSERT ... ON CONFLICT`. В DAG используется безопасная для GP6 конструкция `INSERT ... WHERE NOT EXISTS` внутри транзакции. +- Зафиксируй digest образа `woblerr/greenplum:6.27.1` (Docker Hub → Tag → «Copy digest») и замени тег на `@sha256:...` в `docker-compose.yml`. +- Альтернативы: можно использовать другие образы Greenplum или собрать собственный образ для GPDB 6/7. +- Особенность GPDB 6: в нём **нет** `INSERT ... ON CONFLICT`. В DAG используется безопасная для GP6 конструкция `INSERT ... WHERE NOT EXISTS` внутри транзакции. ## Ограничения и заметки - Этот стенд — учебный. Для высокой надёжности и производительности Greenplum обычно разворачивают кластерами на нескольких узлах, на裸‑железе/VM с отдельными дисками под сегменты. diff --git a/airflow-greenplum/airflow/requirements.txt b/airflow-greenplum/airflow/requirements.txt index 2b28044..a7da61b 100644 --- a/airflow-greenplum/airflow/requirements.txt +++ b/airflow-greenplum/airflow/requirements.txt @@ -1,3 +1,3 @@ confluent-kafka==2.3.0 psycopg2-binary==2.9.9 -pandas==2.2.2 +pandas==2.1.* diff --git a/airflow-greenplum/docker-compose.yml b/airflow-greenplum/docker-compose.yml index 16a7aad..ba8a6e0 100644 --- a/airflow-greenplum/docker-compose.yml +++ b/airflow-greenplum/docker-compose.yml @@ -1,5 +1,3 @@ -version: "3.9" - services: # Postgres только для Airflow метаданных pgmeta: @@ -21,17 +19,23 @@ services: retries: 20 greenplum: - image: datagrip/greenplum:6.8 + image: woblerr/greenplum:6.27.1 # container_name: gp_single - hostname: gpdbsne + # hostname: gpdbsne + environment: + GREENPLUM_USER: ${GP_USER:-gpadmin} + GREENPLUM_PASSWORD: ${GP_PASSWORD:-gpadmin} + GREENPLUM_DATABASE_NAME: ${GP_DB:-gpadmin} + # GP_PORT: ${GP_PORT:-5432} # Порты: внешний 5432 ports: - - "5432:5432" + - "${GP_PORT}:5432" volumes: - ./sql:/sql:ro + - greenplum_data:/data # Простая проверка доступности: psql откликается healthcheck: - test: ["CMD-SHELL", "pg_isready -h 127.0.0.1 -p 5432 || echo 1"] + test: ["CMD-SHELL", "pg_isready -h 127.0.0.1 -p 5432 -U ${GP_USER:-gpadmin} -d ${GP_DB:-gpadmin} || echo 1"] interval: 10s timeout: 5s retries: 30 @@ -143,3 +147,4 @@ services: volumes: pgmeta: kafka-ui-data: + greenplum_data: