18 KiB
Временное ТЗ по PXF для чтения данных из bookings (черновик)
Этот файл внутренний, удалить перед итоговой сдачей.
1. Цель и границы
- Минимальная цель: настроить PXF в контейнере Greenplum так, чтобы из базы
bookings(Postgres в сервисеbookings-db) можно было делатьSELECTпо одной внешней таблице в Greenplum. - На этом этапе не делаем загрузку в постоянные таблицы Greenplum, только чтение и ручные smoke‑проверки.
- Изменения в коде/конфигурации пока планируем «на бумаге»; реализацию и правки
docker-compose.yml/SQL/DAG делаем отдельным шагом.
2. Архитектура на уровне контейнеров
bookings-db— Postgres 16, демо‑БДdemoиз репозиторияdemodb(источник). Доступен внутри сети Docker по имениbookings-dbи порту5432.greenplum— контейнерwoblerr/greenplum:6.27.1(GPDB 6, Ubuntu 22.04). В нём уже есть:- Greenplum в режиме singlenode;
- установленный PXF (
/usr/local/pxf,pxf version release-6.10.1); - стартовый скрипт
/start_gpdb.sh, который умеет включать PXF по флагуGREENPLUM_PXF_ENABLE=true.
- Внешний мир (IDE/pytest) подключается к Greenplum по порту
5435на хосте (см.docker-compose.yml), а кbookings-db— по порту${BOOKINGS_DB_PORT}(см..env).
3. Включение PXF в нашем стенде (дизайн)
Планируемые изменения (позже будут внесены в docker-compose.yml):
- В сервисе
greenplumв секциюenvironmentдобавить:GREENPLUM_PXF_ENABLE: "true".
- При первом старте с этим флагом скрипт
/start_gpdb.shсделает за нас:- инициализацию PXF (
pxf cluster prepare,pxf cluster register,pxf cluster sync); - создание расширения
pxfв базе${GREENPLUM_DATABASE_NAME}(у нас это${GP_DB}, по умолчаниюgp_dwh); - запуск
pxf cluster startи привязку остановки/старта PXF к жизненному циклу Greenplum.
- инициализацию PXF (
- База конфигов PXF (
PXF_BASE) будет располагаться в${GREENPLUM_DATA_DIRECTORY}/pxf, в нашем compose — это/data/pxfна томеgreenplum_data.- Важно:
make downсейчас делаетdocker compose down -v, поэтому при полном сбросе томов будут теряться и данные GP, и конфиги PXF (включая JDBC‑драйвер иservers/*).
- Важно:
4. JDBC‑драйвер для Postgres: где и как хранить
Задача: PXF должен уметь ходить по JDBC в bookings-db (Postgres). Для этого нужен PostgreSQL JDBC драйвер (postgresql-*.jar).
Варианты хранения драйвера:
- Коммитить JAR в репозиторий и монтировать в контейнер.
- Плюсы: стенд самодостаточен, не зависит от внешних скачиваний, повторяемость выше (особенно на офлайн‑машинах или при падении зеркал).
- Минусы: лишний бинарник в учебном репо, периодически нужно обновлять версию.
- Скачивать JAR внутрь контейнера один раз вручную и хранить его в томе
greenplum_dataвнутриPXF_BASE/lib.- Плюсы: нет бинарников в Git.
- Минусы: дополнительный шаг для студентов, зависимость от сети, нужно повторять после полного сброса томов.
Для учебного стенда окончательно выбираем вариант (1) — JAR в репозитории:
- В репозитории заводим каталог, например
pxf/илиpxf/jdbc/, и кладём туда файлpostgresql-42.7.3.jar(фиксируем версию 42.7.3 как актуальную на момент разработки). - В
docker-compose.yml(на этапе реализации) смонтируем этот JAR внутрь контейнераgreenplumв каталог$PXF_BASE/lib, например:./pxf/postgresql-42.7.3.jar:/data/pxf/lib/postgresql-jdbc.jar:ro.
- PXF по документации поддерживает размещение JDBC‑драйвера в
$PXF_BASE/lib(общий для всех серверов) или в$PXF_BASE/servers/<server>/lib(локальный для сервера). Для простоты используем общий каталог$PXF_BASE/lib. - Для студентов не будет лишних подготовительных шагов: после
make upи инициализации конфигов PXF драйвер уже на месте.
Договорённость для реализации:
- Путь в репозитории: условно
pxf/postgresql-42.7.3.jar. - Путь внутри контейнера:
/data/pxf/lib/postgresql-jdbc.jar(через bind‑mount, read‑only). - Обновление драйвера в будущем — ручная операция (заменить JAR в
pxf/и скорректировать путь вdocker-compose.ymlпри необходимости).
5. Сервер PXF для bookings-db (jdbc-site.xml)
PXF использует концепцию «серверов» (servers/<имя>), где для каждого сервера хранится свой конфиг подключения (в т.ч. JDBC).
План:
- Создать сервер с именем
bookings-db(название привязываем к сервису Docker, чтобы не путаться). - Конфиг храним в репозитории, например в файле:
pxf/servers/bookings-db/jdbc-site.xml.
- В контейнере этот файл будет доступен как:
/data/pxf/servers/bookings-db/jdbc-site.xml(bind‑mount read‑only).
- Внутри прописываем параметры подключения к демо‑БД
demoв Postgresbookings-db.
Черновой шаблон jdbc-site.xml (значения логина/пароля берём из .env.example, блок BOOKINGS_DB_* — для учебного стенда допускаем хардкод тех же дефолтных значений):
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<property>
<name>jdbc.driver</name>
<value>org.postgresql.Driver</value>
</property>
<property>
<name>jdbc.url</name>
<value>jdbc:postgresql://bookings-db:5432/demo</value>
</property>
<property>
<name>jdbc.user</name>
<value>${BOOKINGS_DB_USER}</value>
</property>
<property>
<name>jdbc.password</name>
<value>${BOOKINGS_DB_PASSWORD}</value>
</property>
</configuration>
Замечания:
- В реальном файле
pxf/servers/bookings-db/jdbc-site.xmlлогин и пароль будут прописаны строками, совпадающими с дефолтами из.env.example(BOOKINGS_DB_USER=bookings,BOOKINGS_DB_PASSWORD=bookings). Это упрощает старт стенда для студентов. - Если студент поменяет креды
BOOKINGS_DB_USER/BOOKINGS_DB_PASSWORDв своём.env, он должен также поменять их вpxf/servers/bookings-db/jdbc-site.xml, иначе PXF не сможет подключиться к источнику. - Адрес
bookings-db:5432— имя сервиса и внутренний порт Postgres внутри сетиdocker compose. Внешний порт (${BOOKINGS_DB_PORT:-5434}) здесь не используется. - При стандартном сценарии (конфиг монтируется read‑only) PXF подхватывает
jdbc-site.xmlпри первой инициализации/старте. Если конфиг внутри контейнера всё‑таки меняли вручную, для надёжности можно выполнить:чтобы PXF подхватил новые настройки.pxf cluster sync pxf cluster restart
6. Внешняя таблица в Greenplum (только для чтения)
Задача: завести одну external‑таблицу в Greenplum, которая читает данные из демо‑БД demo через PXF/JDBC.
Дизайн:
- Имя таблицы в Greenplum:
public.ext_bookings_bookings(подчёркиваем, что это внешнее представление таблицыbookings.bookingsиз Postgres). - Схема колонок должна совпадать со схемой исходной таблицы в
demo(её нужно будет аккуратно выписать отдельным шагом, через\d bookings.bookingsвbookings-db). - Локация PXF:
PROFILE=JDBC— используем JDBC‑профиль.SERVER=bookings-db— имя сервера изjdbc-site.xml.
Черновой шаблон DDL (без конкретных типов, заполним позже по реальной схеме; предполагается, что финальный DDL ляжет в sql/ddl_gp.sql, чтобы применяться через make ddl-gp):
CREATE EXTERNAL TABLE public.ext_bookings_bookings (
-- TODO: колонки как в bookings.bookings (будет уточнено)
)
LOCATION ('pxf://bookings.bookings?PROFILE=JDBC&SERVER=bookings-db')
FORMAT 'CUSTOM' (formatter='pxfwritable_import');
Комментарии:
- На этапе реализации нужно будет:
- в
bookings-dbпосмотреть структуру основного факт‑табличного объекта (скорее всегоbookings.bookings) и перенести DDL; - проверить типы дат/чисел, чтобы избежать сюрпризов на стороне GP.
- в
- Для MVP достаточно одной таблицы; позже можно добавить ещё 1–2 внешние таблицы для примеров (например, справочники).
7. План тестирования (без дополнительных make‑таргетов)
Цель тестов: показать студентам, что PXF настроен корректно и позволяет читать данные; при этом не плодить отдельные make‑цели, а использовать уже существующие (make up, make bookings-init, make gp-psql).
7.1. Позитивный сценарий (smoke)
Предварительные условия:
.envскопирован из.env.exampleи не изменял дефолтные креды дляbookings-db(BOOKINGS_DB_USER=bookings,BOOKINGS_DB_PASSWORD=bookings).- В
docker-compose.ymlвключён PXF (GREENPLUM_PXF_ENABLE=trueв сервисеgreenplum). - Для
bookings-dbуже выполненmake bookings-init(есть данные вdemo). - JAR драйвера (
pxf/postgresql-42.7.3.jar) и файлjdbc-site.xml(pxf/servers/bookings-db/jdbc-site.xml) присутствуют в репозитории (они будут автоматически смонтированы в/data/pxf/libи/data/pxf/servers/bookings-db). - DDL внешней таблицы
public.ext_bookings_bookingsдобавлен вsql/ddl_gp.sqlи применяется черезmake ddl-gp.
Шаги (в будущем попадут в TESTING.md):
- Поднять стенд:
make up- дождаться healthcheck‑ов
pgmetaиgreenplum.
- Инициализировать Airflow (если ещё не делали):
make airflow-init.
- Подготовить демо‑БД bookings:
make bookings-init.
- Применить DDL в Greenplum (создать таблицы, включая внешнюю
public.ext_bookings_bookings):make ddl-gp.
- Зайти в Greenplum:
make gp-psql.
- Проверить, что расширение PXF присутствует:
\dx pxf.
- Выполнить простые запросы:
SELECT COUNT(*) FROM public.ext_bookings_bookings;SELECT * FROM public.ext_bookings_bookings LIMIT 5;
Ожидаемый результат:
- Запросы выполняются без ошибок, возвращают ненулевое количество строк.
- Структура данных визуально совпадает с данными в
bookings-db(можно дополнительно открытьbookings-psqlи сравнить).
7.2. Негативный сценарий (отказ источника)
Цель: показать, как выглядит ошибка, если источник недоступен, и что с этим делать.
Шаги:
- При работающем стенде остановить только
bookings-db:docker compose stop bookings-db.
- В
make gp-psqlпопробовать снова:SELECT 1 FROM public.ext_bookings_bookings LIMIT 1;
Ожидаемый результат:
- Запрос падает с ошибкой подключения к Postgres (через JDBC/pxf).
- В
TESTING.mdпланируем добавить короткую подсказку: «если видите ошибку подключения — убедитесь, что запущен сервисbookings-db(docker compose start bookings-db) и повторите запрос».
7.3. Идея для автоматического smoke‑теста (на будущее)
На будущее (не в рамках текущего этапа) можно добавить простой e2e‑тест в tests/, который:
- с помощью
psycopg2коннектится к Greenplum (GP_*из.env); - выполняет
SELECT 1 FROM public.ext_bookings_bookings LIMIT 1; - помечен как «integration» и запускается только по явному желанию (например, через отдельный маркер или переменную окружения).
Пока это остаётся идеей: сначала реализуем базовую конфигурацию PXF и ручной smoke‑чек‑лист.
8. Открытые вопросы / TODO
- Уточнить целевую таблицу(ы) в
demoдля внешнего представления (скорее всегоbookings.bookings), аккуратно выписать DDL и обновить шаблон из раздела 6. - При переносе DDL проверить типы дат/времени, чтобы не получить неожиданный сдвиг по часовому поясу (см.
docs/internal/bookings_tz.md). - При необходимости добавить интеграционный тест по мотивам раздела 7.3 (по отдельному маркеру/флагу).
9. Практические детали и нюансы
- Таймзона:
- Для единообразия логов и данных задаём
TZ=Europe/Moscow(GMT+3) в.env.exampleи пробрасываем эту переменную в контейнерыpgmeta,bookings-db,greenplum,airflow-webserver,airflow-scheduler. - При проверке данных через PXF имеет смысл сравнивать выборки по времени между
bookings-dbи Greenplum, опираясь на договорённости изdocs/internal/bookings_tz.md.
- Для единообразия логов и данных задаём
- Поведение при
make down:make downвызываетdocker compose down -v, что удаляет все тома, включаяgreenplum_data(/dataв контейнере).- При следующем
make upGreenplum и PXF будут инициализироваться с нуля, но:- JAR и
jdbc-site.xmlвозьмутся из репозитория и снова смонтируются в/data/pxf/...; make ddl-gpснова создаст внешнюю таблицуpublic.ext_bookings_bookings.
- JAR и
- То есть после полного ресета студенту достаточно повторить цепочку
make up→make airflow-init→make bookings-init→make ddl-gp.
- Где искать логи при проблемах с PXF:
- Логи PXF: в контейнере
greenplumпод пользователемgpadminв каталоге${PXF_BASE}/logs(по умолчанию/data/pxf/logs). - Логи Greenplum: в
${GREENPLUM_DATA_DIRECTORY}/master/.../pg_log(например,/data/master/gpseg-1/pg_logдля GP6). - При ошибках подключения к
bookings-dbполезно:- проверить, что контейнер
bookings-dbработает (docker compose ps); - сверить креды в
.envиpxf/servers/bookings-db/jdbc-site.xml; - посмотреть сообщения в
/data/pxf/logs.
- проверить, что контейнер
- Логи PXF: в контейнере