34.7. Использование встроенной аналитической платформы #
34.7.1. Начало #
Чтобы начать работу со встроенной аналитической платформой, выполните следующие действия:
Прочитайте информацию об особенностях и ограничениях и убедитесь, что расширение pgpro_duckdb соответствует внутренним требованиям вашей организации, а также профилю нагрузки аналитических запросов.
Подготовьте диаграмму оптимального развёртывания. За более подробной информацией обратитесь к разделу Рекомендации по развёртыванию.
Установите расширение pgpro_duckdb.
Выделите необходимые ресурсы. За более подробной информацией обратитесь к разделу Планирование ресурсов.
Определите модель безопасности для работы с OLAP-ресурсами. За более подробной информацией обратитесь к разделу Настройка безопасного доступа к OLAP-ресурсам.
Установите ограничения ресурсов для аналитических запросов с учётом OLTP-нагрузки. За более подробной информацией обратитесь к разделу Настройка ограничений вычислительных ресурсов.
Выдайте пользователям pgpro_duckdb необходимые права доступа.
Экспортируйте необходимые OLAP-данные в столбцовое представление, затем переместите их в соответствующее хранилище. За более подробной информацией обратитесь к разделу Экспорт OLAP-данных в хранилище.
Создайте представления для экспортированных Parquet-файлов. За более подробной информацией обратитесь к разделу Создание представления для работы с Parquet-файлами.
Убедитесь, что аналитические запросы могут быть выполнены на созданных представлениях.
34.7.2. Настройка безопасного доступа к OLAP-ресурсам #
Чтобы настроить безопасный доступ к OLAP-ресурсам, настройте ролевой доступ и хранилища.
34.7.2.1. Настройка ролевого доступа #
Вы можете использовать параметр конфигурации duckdb.postgres_role, чтобы указать имя роли, которая может вызывать функции pgpro_duckdb:
postgres=# show duckdb.postgres_role; duckdb.postgres_role ---------------------- (1 row)
По умолчанию для параметра конфигурации duckdb.postgres_role
указано значение NULL, то есть вызывать функции pgpro_duckdb может только суперпользователь:
postgres=> SELECT usename, usesuper FROM pg_user WHERE usename = current_user; usename | usesuper ---------+---------- user1 | f (1 row) postgres=> SELECT * FROM duckdb.query('SELECT * FROM a;'); ERROR: DuckDB execution is not allowed because you have not been granted the duckdb.postgres_role
Чтобы разрешить членам пользовательской роли вызывать функции pgpro_duckdb, укажите имя требуемой роли, после чего перезапустите сервер:
postgres=# ALTER SYSTEM SET duckdb.postgres_role TO 'user1'; ALTER SYSTEM -- после перезапуска сервера -- postgres=# show duckdb.postgres_role ; duckdb.postgres_role ---------------------- user1 (1 row)
34.7.2.2. Настройка хранилищ #
Вы можете использовать параметр конфигурации duckdb.disabled_filesystems, чтобы указать хранилища, которые будут отключены для расширения pgpro_duckdb.
Возможные значения:
LocalFileSystem
: локальное хранилищеS3FileSystem
: S3-хранилищеHTTPFileSystem
: сетевое хранилище
По умолчанию локальное хранилище отключено:
postgres=> show duckdb.disabled_filesystems; duckdb.disabled_filesystems ----------------------------- LocalFileSystem (1 row)
Примечание
Перед включением локального или S3-хранилища обратитесь к разделам Особенности работы с локальным хранилищем и Рекомендации по работе с S3-хранилищем.
Чтобы указать несколько хранилищ, разделите их имена запятыми без пробелов:
postgres=# ALTER SYSTEM SET duckdb.disabled_filesystems TO 'LocalFileSystem,HTTPFileSystem'; ALTER SYSTEM -- после перезапуска сервера -- postgres=# show duckdb.disabled_filesystems; duckdb.disabled_filesystems -------------------------------- LocalFileSystem,HTTPFileSystem (1 row)
34.7.2.2.1. Особенности работы с локальным хранилищем #
Локальное хранилище по умолчанию отключено, поэтому пользователям запрещено экспортировать или читать из него файлы:
postgres=> show duckdb.disabled_filesystems; duckdb.disabled_filesystems ----------------------------- LocalFileSystem (1 row) postgres=> COPY test TO 'out.parquet'; ERROR: (PGDuckDB/DuckdbUtilityHook_Cpp) Permission Error: File system LocalFileSystem has been disabled by configuration postgres=> SELECT * FROM read_parquet('test.parquet'); ERROR: (PGDuckDB/CreatePlan) Prepared query returned an error: 'Permission Error: File system LocalFileSystem has been disabled by configurationinput>
Если локальное хранилище включено, члены роли, указанной в параметре конфигурации duckdb.postgres_role, имеют такие же права доступа в этом хранилище, как и пользователь postgres
. Это необходимо для чтения из Parquet-файлов и записи в них:
postgres=> show duckdb.disabled_filesystems; duckdb.disabled_filesystems ----------------------------- (1 row) postgres=> COPY test TO 'out.parquet'; COPY 7 postgres=> SELECT * FROM read_parquet('out.parquet'); a | b ---+--- 1 | 2 ... (7 rows)
Однако в этом случае пользователи также имеют доступ к файлам в каталоге PGDATA
:
postgres=> show duckdb.disabled_filesystems ; duckdb.disabled_filesystems ----------------------------- (1 row) postgres=> SELECT pg_read_file('postgresql.auto.conf'); ERROR: permission denied for function pg_read_file postgres=> SELECT * FROM duckdb.query('SELECT content FROM read_text(''postgresql.auto.conf'')'); content ------------------------------------------------------- # Не редактируйте этот файл вручную! + # Он будет перезаписан командой ALTER SYSTEM.+
В то время как если вы отключите локальное хранилище:
postgres=> show duckdb.disabled_filesystems ; duckdb.disabled_filesystems ----------------------------- LocalFileSystem (1 row) postgres=> SELECT * FROM duckdb.query('SELECT content FROM read_text(''postgresql.auto.conf'')'); ERROR: (PGDuckDB/CreatePlan) Prepared query returned an error: 'Permission Error: File system LocalFileSystem has been disabled by configuration
Рекомендации по использованию расширения pgpro_duckdb с локальным хранилищем:
Используйте локальное хранилище, только если вы уверены, что пользователи будут правильно вызывать функции pgpro_duckdb.
Изолируйте процессы Postgres Pro от файлов вне каталога
PGDATA
и файлов, которые будут прочитаны или записаны.
34.7.2.2.2. Рекомендации по работе с S3-хранилищем #
Для работы с S3-хранилищем укажите информацию о подключении. Например, если у вас развёрнут экземпляр S3-хранилища MinIO, выполните следующие действия от имени пользователя postgres
:
Создайте сервер для S3-хранилища:
postgres=# CREATE SERVER my_secret1 TYPE 's3' FOREIGN DATA WRAPPER duckdb OPTIONS ( endpoint '127.0.0.1:9000', url_style 'path', use_ssl 'FALSE' ); CREATE SERVER
Создайте сопоставление пользователей для пользователя, который будет работать с S3-хранилищем:
postgres=# CREATE USER MAPPING FOR user1 SERVER my_secret1 OPTIONS (KEY_ID 'minioadmin', SECRET 'minioadmin'); CREATE USER MAPPING
Указанный пользователь теперь имеет права доступа, необходимые для работы с S3-хранилищем:
postgres=> SELECT * FROM read_parquet('s3://bucket1/results.parquet'); a | b ---+--- 1 | 2 2 | (2 rows) postgres=> COPY a TO 's3://bucket1/a.parquet'; COPY 8
Если вы создаёте сопоставление пользователей для пользовательской роли, указанной в параметре конфигурации duckdb.postgres_role, все члены этой роли смогут работать с S3-хранилищем.
Чтобы отозвать доступ к S3-хранилищу у пользователя, удалите соответствующее сопоставление пользователей:
postgres=# DROP USER MAPPING FOR user1 SERVER my_secret1; DROP USER MAPPING
Чтобы отозвать доступ к S3-хранилищу у всех пользователей, отключите хранилище:
postgres=> show duckdb.disabled_filesystems ; duckdb.disabled_filesystems ------------------------------ LocalFileSystem,S3FileSystem (1 row) postgres=> SELECT * FROM read_parquet('s3://bucket1/results.parquet'); ERROR: (PGDuckDB/CreatePlan) Prepared query returned an error: 'Permission Error: File system S3FileSystem has been disabled by configuration postgres=> COPY a TO 's3://bucket1/a.parquet'; ERROR: (PGDuckDB/DuckdbUtilityHook_Cpp) Permission Error: File system S3FileSystem has been disabled by configuration
34.7.3. Экспорт OLAP-данных в хранилище #
Особенности экспорта OLAP-данных в хранилище:
Метод сжатия zstd с уровнем сжатия по умолчанию обеспечивает оптимальное соотношение размера файла и скорости выполнения операций.
Вы можете указать размер файла с помощью параметра
FILE_SIZE_BYTES
. Значение должно быть в диапазоне от 100 МБ до 10 ГБ.Вы можете не изменять параметр
ROW_GROUP_SIZE
.
34.7.3.1. Экспорт OLAP-данных в столбцовое представление #
OLAP-данные экспортируются с помощью команды COPY
. Вы можете экспортировать таблицу Postgres Pro целиком:
COPY tbl TO 'output.parquet' (FORMAT parquet);
Или только необходимые OLAP-данные:
COPY (SELECT * FROM tbl) TO 'output.parquet' (FORMAT parquet);
Вы можете использовать следующие рекомендации по структуре каталогов и экспорту в Parquet-файлы:
COPY (SELECT * FROM tbl) TO '/rootpath/db_name/schema_name/ table_name'
(FORMAT parquet, COMPRESSION zstd, FILE_SIZE_BYTES 1g);
34.7.3.2. Экспорт OLAP-данных в S3-хранилище #
Чтобы экспортировать OLAP-данные в S3-хранилище, укажите информацию о подключении. Например, если у вас развёрнут экземпляр S3-хранилища MinIO, выполните следующие действия от имени пользователя postgres
:
Создайте сервер для S3-хранилища:
postgres=# CREATE SERVER my_secret1 TYPE 's3' FOREIGN DATA WRAPPER duckdb OPTIONS ( endpoint '127.0.0.1:9000', url_style 'path', use_ssl 'FALSE' ); CREATE SERVER
Создайте сопоставление пользователей для пользователя, который будет работать с S3-хранилищем:
postgres=# CREATE USER MAPPING FOR user1 SERVER my_secret1 OPTIONS (KEY_ID 'minioadmin', SECRET 'minioadmin'); CREATE USER MAPPING
Выполните команду
COPY
от имени требуемого пользователя:COPY (SELECT * FROM tbl) TO 's3://bucket/db_name/schema_name/table_name' (FORMAT parquet, COMPRESSION zstd, FILE_SIZE_BYTES 1g);
34.7.3.3. Поддержка секционирования #
Чтобы организовать OLAP-данные по ключам секционирования в каталоге таблиц Postgres Pro с помощью Hive-секционирования, укажите параметр PARTITION_BY
при экспорте данных:
COPY (SELECT * FROM tbl) TO 's3://bucket/db_name/schema_name/table_name' (FORMAT parquet, PARTITION_BY (year, month), COMPRESSION zstd);
Так как запись большого количества Parquet-файлов является ресурсоёмкой OLAP-операцией, выбирайте ключи секционирования таким образом, чтобы размер каждой итоговой секции составлял как минимум 100 МБ. Размер Parquet-файлов невозможно настроить вместе с параметром PARTITION_BY
. Количество создаваемых в каждом каталоге (секции) Parquet-файлов соответствует количеству потоков pgpro_duckdb.
За более подробной информацией о команде COPY
и формате Parquet обратитесь к официальной документации DuckDB по операторам и Parquet-файлам.
34.7.3.4. Транзакции и производительность #
Команда COPY
выполняется в транзакции, потому снимок экспортированной таблицы Postgres Pro получается согласованным. Вы можете использовать явную транзакцию, чтобы экспортировать несколько согласованных таблиц, несколько раз подряд выполнив команду COPY
.
Открытые транзакции откладывают очистку, что может негативно повлиять на производительность и увеличить размер таблиц. Чтобы этого избежать, выполните следующие действия:
При наличии доступных вычислительных ресурсов выполните команду
COPY
для каждой таблицы в отдельном сеансе. В этом случае в каждом сеансе необходимо подключиться к одному и тому же снимку транзакции с помощью командыSET TRANSACTION SNAPSHOT
.Как правило, таблицы, доступные только для добавления, имеют столбец с монотонно увеличивающимися значениями. Вы можете разделить значения на диапазоны и экспортировать их в разных транзакциях.
Обратите внимание, что вы можете указать количество процессов postgres
для чтения таблиц, а также количество потоков pgpro_duckdb для экспорта OLAP-данных в Parquet-файлы. Однако конвертация из столбцового в строчное представление в настоящее время выполняется в одном потоке.
34.7.3.5. Ошибки экспорта #
Если при экспорте OLAP-данных в Parquet-файлы возникает ошибка, например из-за недостаточного дискового пространства, частично экспортированные файлы не удаляются. Для таких случаев необходимо настроить автоматическое удаление и продолжение работы.
34.7.4. Создание представления для работы с Parquet-файлами #
Расширение pgpro_duckdb использует функцию read_parquet для чтения Parquet-файлов. Эта функция возвращает специальный тип данных — duckdb.row
, который обеспечивает совместимость между DuckDB и Postgres Pro. Функция read_parquet
использует уникальный синтаксис для работы со столбцами:
SELECT r['id'], r['name'] FROM read_parquet('file.parquet') r WHERE r['age'] > 21;
34.7.4.1. Создание представления для Parquet-файлов #
После экспорта OLAP-данных в Parquet-файлы вы можете работать с ними как со стандартными таблицами Postgres Pro. Для этого создайте представление для Parquet-файлов:
CREATE VIEW parquet_table AS
SELECT
r['id']::BIGINT AS id,
r['age']::SMALLINT AS age,
r['name']::VARCHAR AS name
FROM read_parquet('file.parquet') AS r;
В этом примере явно указаны используемые в Parquet-файлах типы данных. Это необязательно, но так вы можете назначить столбцам необходимые типы DuckDB. В противном случае будут использованы метаданные Parquet-файлов. Если типы данных не указаны явно, описание представления будет содержать уникальный тип данных duckdb.unresolved_type
.
После создания представления можно выполнять стандартные аналитические запросы:
SELECT id, name FROM parquet_table r WHERE age > 21;
34.7.4.2. Работа с Parquet-файлами с помощью шаблона поиска (glob pattern) #
Функция read_parquet
может принимать списки имён Parquet-файлов. Она также позволяет использовать синтаксис шаблона поиска и указывать списки шаблонов поиска. Синтаксис шаблона поиска можно использовать для чтения каталога Parquet-файлов или нескольких каталогов, если используется Hive-секционирование.
За более подробной информацией обратитесь к официальной документации DuckDB по Parquet-файлам.
34.7.4.3. Оптимизация производительности для Parquet-файлов #
Расширение pgpro_duckdb содержит следующие оптимизации производительности для Parquet-файлов:
Перенос проекций на файловый уровень (projection pushdown): исключает не указанные в аналитических запросах столбцы.
Перенос фильтров на файловый уровень (filter pushdown): использует метаданные Parquet-файлов для чтения строк.
Hive-секционирование: уменьшает объём читаемых OLAP-данных. Вы можете организовать OLAP-данные по ключам секционирования в иерархии каталогов и использовать ключи секционирования в аналитических запросах. В этом случае будут прочитаны только каталоги, соответствующие указанным ключам секционирования.
За более подробной информацией обратитесь к официальной документации DuckDB по частичному чтению и переносу фильтров на файловый уровень.
34.7.5. Настройка ограничений вычислительных ресурсов #
Чтобы избежать негативного влияния на OLTP-нагрузки, важно ограничивать потребление вычислительных ресурсов аналитическими сеансами.
34.7.5.1. Ограничение потоков и потребления памяти #
Расширение pgpro_duckdb позволяет ограничивать количество потоков и потребление памяти для аналитических сеансов с помощью следующих параметров конфигурации:
Реальное потребление памяти операционной системой может быть выше. Например, настроенные ограничения не учитываются процессом выделения пространства для результатов запросов. За более подробной информацией обратитесь к официальной документации DuckDB по управлению ресурсами.
34.7.5.2. Перенос данных на диск #
Расширение pgpro_duckdb обрабатывает OLAP-данные в потоках, то есть часть за частью, по возможности избегая полной материализации. Если расширению pgpro_duckdb не хватает оперативной памяти для выполнения аналитического запроса, связанные данные помещаются во временные файлы, что существенно повышает время выполнения.
Временные файлы размещаются в каталоге PGDATA/.tmp
и могут занимать до 90% дискового пространства. Каждые 24 часа выполняйте мониторинг количества временных файлов, создаваемых расширением pgpro_duckdb, и избегайте пиковых значений.
34.7.5.3. Результаты синтетических тестов одновременных нагрузок OLAP и OLTP #
Для оценки производительности был использован CH-benCHmark. Он включает в себя измерение среднего количества транзакций в секунду (TPS) за определённый период времени, а также количества параллельно выполненных аналитических запросов. В этом случае характер аналитических запросов не имеет значения, так как они выполняются в случайном порядке, и время выполнения одного аналитического запроса гораздо меньше продолжительности запуска теста.
OLTP-нагрузка была обеспечена программой pgbench, а аналитические запросы ClickBench были сгенерированы на фоне скриптом. В файле CH-benCHmark аналитические запросы TCP-H были заменены запросами ClickBench. В качестве изначальной реализации был использован citus-benchmark.
Описание теста:
Сервер с 64 виртуальными процессорами и 128 ГБ оперативной памяти
Размер данных: 14 ГБ для каждого набора данных pgbench и ClickBench, обработано в оперативной памяти
Продолжительность теста: 100 секунд
Метрики: транзакции в секунду (TPS), количество аналитических запросов и средняя нагрузка
34.7.5.3.1. Тест 1 #
Для этого теста был запущен один процесс ClickBench с 4 потоками. Количество подключений pgbench -S (select-only) отличалось для каждого запуска теста.
Таблица 34.2. Результаты теста 1
Количество подключений | TPS / аналитические запросы (средняя нагрузка) |
---|---|
25 | 287/39 (23.8) |
50 | 487/39 (42) |
100 | 532/38 (68) |
200 | 610/34 (158) |
34.7.5.3.2. Тест 2 #
Для этого теста были запущены 200 подключений pgbench -S (select-only). Количество процессов ClickBench с 2 потоками отличалось для каждого запуска теста.
Таблица 34.3. Результаты теста 2
Количество процессов ClickBench | TPS / аналитические запросы (средняя нагрузка) |
---|---|
2 | 574/49 (147) |
4 | 533/66 (156) |
8 | 522/127 (170) |
34.7.5.3.3. Тест 3 #
Для этого теста были запущены 200 подключений pgbench TCP-B. Количество потоков отличалось для каждого запуска теста.
Таблица 34.4. Результаты теста 3
Количество потоков | TPS / аналитические запросы (средняя нагрузка) |
---|---|
0 | 53 |
1 | 42/17 (66) |
4 | 42/39 (69) |
Не ограничено | 42/108 (86) |
34.7.5.4. Одновременная нагрузка OLAP и OLTP #
Рекомендации для одновременной нагрузки OLAP и OLTP:
Если OLTP-сеансы используют много ядер ЦП, вы можете запустить ограниченное количество OLAP-потоков без оказания негативного влияния OLTP-нагрузку. Это обеспечивает планировщик ОС, который равномерно распределяет ресурсы ЦП между потоками.
Ограничьте количество потоков и потребление памяти аналитическими сеансами с помощью параметров конфигурации pgpro_duckdb.
Храните Parquet-файлы и каталог временных файлов в автономном физическом хранилище, чтобы избежать конкуренции между вводом и выводом.
34.7.6. Базовый сценарий работы аналитика #
В этом разделе описан базовый сценарий работы аналитика. Предполагается, что выполнены следующие предварительные требования:
Postgres Pro развёрнут с установленным расширением pgpro_duckdb.
Экземпляр S3-хранилища MinIO развёрнут и содержит Parquet-файлы.
Приложение DBeaver установлено и подключено к базе данных.
Базовый сценарий состоит из следующих шагов:
Настройка расширения pgpro_duckdb и S3-хранилища MinIO. Администратор создаёт сервер для S3-хранилища и сопоставление пользователей для пользователя, который будет работать с S3-хранилищем. Команды выполняются от имени пользователя
postgres
:postgres=# CREATE SERVER my_secret1 TYPE 's3' FOREIGN DATA WRAPPER duckdb OPTIONS ( endpoint '127.0.0.1:9000', url_style 'path', use_ssl 'FALSE' ); CREATE SERVER postgres=# CREATE USER MAPPING FOR user1 SERVER my_secret1 OPTIONS (KEY_ID 'minioadmin', SECRET 'minioadmin'); CREATE USER MAPPING
Создание представления для работы с Parquet-файлами:
postgres=# CREATE VIEW orders_view AS SELECT r['o_orderkey']::bigint o_orderkey, r['o_custkey']::bigint o_custkey, r['o_orderstatus']::char o_orderstatus, r['o_totalprice']::double precision o_totalprice, r['o_orderdate']::date o_orderdate, r['o_orderpriority']::text o_orderpriority, r['o_clerk']::text o_clerk, r['o_shippriority']::bigint o_shippriority, r['o_comment']::text o_comment FROM read_parquet('s3://bucket1/orders/orders.parquet') r; CREATE VIEW
В этом запросе столбцы выбираются из Parquet-файла с помощью параметра
r['
, и типы данных указаны синтаксисомимя_столбца
']r['
имя_столбца
']::тип
. Кроме того, для удобства работы с данными созданы псевдонимы столбцов, а также псевдонимr
для параметраread_parquet
.Теперь аналитик может работать с созданным представлением:
test=# SELECT o_orderkey, o_totalprice FROM orders_view LIMIT 3; o_orderkey | o_totalprice ------------+-------------- 1 | 224560.83 2 | 75388.65 3 | 255287.36 (3 rows) test=# SELECT AVG(o_totalprice) FROM orders_view ; AVG ------------------- 151121.1229494574 (1 row)
Работа с созданным представлением с помощью приложения DBeaver. Аналитик может подключаться к базе данных, работать с созданным представлением и выполнять аналитические запросы. Приложение DBeaver отображает типы столбцов, указанные при создании представления.