Привет, Я DocuDroid!
Оценка ИИ поиска
Спасибо за оценку нашего ИИ поиска!
Мы будем признательны, если вы поделитесь своими впечатлениями, чтобы мы могли улучшить наш ИИ поиск для вас и других читателей.
GitHub

Использование коннектора PXF object store для чтения и записи данных в формате Parquet между Greengage DB и S3

Антон Монаков

Apache Parquet — это открытый формат данных с колоночным хранением, используемый в экосистеме Apache Hadoop. Файл данных Parquet содержит компактное двоичное представление данных и включает встроенную схему. Схема определяет структуру данных и состоит из примитивных и сложных типов, перечисленных в разделе Сопоставление типов данных.

В этой статье описывается настройка и использование коннектора PXF object store для чтения и записи данных Parquet в объектном хранилище с использованием внешних таблиц, а также приводятся практические примеры.

Сопоставление типов данных

Для чтения и записи примитивных типов данных Parquet в Greengage DB необходимо сопоставить значения данных Parquet столбцам Greengage DB того же типа.

Parquet поддерживает небольшой набор примитивных типов данных и использует аннотации метаданных, которые указывают, как интерпретировать примитивный тип и расширить его до логического типа. Например, типы INTEGER и DATE хранятся в Parquet как примитивный тип INT32, а аннотация идентифицирует исходный тип как DATE.

Сопоставление при чтении

При чтении данных Parquet в PXF используется следующее сопоставление типов данных.

Физический тип данных Parquet Логический тип данных Parquet Тип данных PXF / Greengage DB

boolean

 — 

BOOLEAN

binary (byte_array)

 — 

BYTEA

binary (byte_array)

Date

DATE

binary (byte_array)

Timestamp_millis

TIMESTAMP

binary (byte_array)

UTF8

TEXT

double

 — 

FLOAT8

fixed_len_byte_array

Decimal

NUMERIC

float

 — 

REAL

int32

int_8

SMALLINT

int32

Date

DATE

int32

Decimal

NUMERIC

int32

 — 

INTEGER

int64

Decimal

NUMERIC

int64

 — 

BIGINT

int96

 — 

TIMESTAMP

ПРИМЕЧАНИЕ

PXF поддерживает pushdown предикатов для всех вышеперечисленных типов данных, кроме fixed_len_byte_array и int96.

PXF может читать данные Parquet составного типа LIST, если они представляют собой одномерный массив следующих типов данных Parquet.

Тип данных Parquet Тип данных PXF / Greengage DB

Список <boolean>

BOOLEAN[]

Список <binary>

BYTEA[]

Список <binary> (Date)

DATE[]

Список <binary> (Timestamp_millis)

TIMESTAMP[]

Список <binary> (UTF8)

TEXT[]

Список <double>

FLOAT8[]

Список <fixed_len_byte_array> (Decimal)

NUMERIC[]

Список <float>

REAL[]

Список <int32> (int_8)

SMALLINT[]

Список <int32> (Date)

DATE[]

Список <int32> (Decimal)

NUMERIC[]

Список <int32>

INTEGER[]

Список <int64> (Decimal)

NUMERIC[]

Список <int64>

BIGINT[]

Список <int96>

TIMESTAMP[]

Сопоставление при записи

При записи данных Parquet в PXF используется следующее сопоставление типов данных.

Тип данных PXF / Greengage DB Физический тип данных Parquet Логический тип данных Parquet

BIGINT

int64

 — 

BOOLEAN

boolean

 — 

BPCHAR (1)

binary (byte_array)

UTF8

BYTEA

binary (byte_array)

 — 

DATE

int32

Date

FLOAT8

double

 — 

INTEGER

int32

 — 

NUMERIC / DECIMAL

fixed_len_byte_array

Decimal

REAL

float

 — 

SMALLINT

int32

int_8

TEXT

binary (byte_array)

UTF8

TIMESTAMP (2)

int96

 — 

TIMESTAMPTZ (3)

int96

 — 

VARCHAR

binary (byte_array)

UTF8

Прочие типы данных

Не поддерживаются

 — 

PXF может записывать данные одномерного массива LIST следующих типов данных Parquet.

Тип данных PXF / Greengage DB Тип данных Parquet

BIGINT[]

Список <int64>

BOOLEAN[]

Список <boolean>

BPCHAR[] (1)

Список <binary> (UTF8)

BYTEA[]

Список <binary>

DATE[]

Список <int32> (Date)

FLOAT8[]

Список <double>

INTEGER[]

Список <int32>

NUMERIC[] / DECIMAL[]

Список <fixed_len_byte_array> (Decimal)

REAL[]

Список <float>

SMALLINT[]

Список <int32> (int_8)

TEXT[]

Список <binary> (UTF8)

TIMESTAMP[] (2)

Список <int96>

TIMESTAMPTZ[] (3)

Список <int96>

VARCHAR[]

Список <binary> (UTF8)

Прочие типы данных

Не поддерживаются

  1. Parquet не сохраняет длину поля, поэтому BPCHAR, записанный в Parquet, будет текстом неопределенной длины.

  2. PXF приводит тип TIMESTAMP к текущему системному часовому поясу, преобразует его во всемирное координированное время (UTC), а затем конвертирует в int96.

  3. PXF преобразует тип TIMESTAMPTZ в метку времени в формате UTC, а затем конвертирует ее в int96. При этом информация о часовом поясе теряется.

Создание внешней таблицы с использованием протокола PXF

Чтобы создать внешнюю таблицу Greengage DB для чтения и записи данных Parquet в объектном хранилище, используется следующий синтаксис:

CREATE [READABLE | WRITABLE] EXTERNAL TABLE <table_name>
    ( <column_name> <data_type> [, ...] | LIKE <other_table> )
    LOCATION ('pxf://<path_to_data>?PROFILE=<objstore>:parquet[&<custom_option>=<value>[...]]')
    FORMAT 'CUSTOM' (FORMATTER='pxfwritable_import'|'pxfwritable_export')
    [DISTRIBUTED BY (<column_name> [, ... ] ) | DISTRIBUTED RANDOMLY];
Ключевое слово Значение

<table_name>

Имя создаваемой таблицы

<column_name>

Имя создаваемого столбца

<data_type>

Тип данных создаваемого столбца

LIKE <other_table>

Указывает таблицу, из которой внешняя таблица копирует все имена столбцов, типы данных и политику распределения

<path_to_data>

Путь к каталогу или файлу в объектном хранилище. Если в конфигурации сервера <server_name> указано свойство pxf.fs.basePath, значение <path_to_data> трактуется как относительный путь к указанному базовому пути. В противном случае путь считается абсолютным. Значение пути не должно содержать символ $

PROFILE=<objstore>:parquet

Профиль указывается в виде пары <objstore>:parquet, где <objstore> — префикс объектного хранилища.

Поддерживаются следующие префиксы <objstore> и соответствующие объектные хранилища:

  • wasbs — Azure Blob Storage

  • adl — Azure Data Lake

  • gs — Google Cloud Storage

  • s3 — Amazon S3, MinIO и прочие S3-совместимые объектные хранилища

FORMAT 'CUSTOM'

Для чтения и записи данных Parquet в объектном хранилище используется кастомный формат с использованием встроенных кастомных функций форматирования для операций чтения (pxfwritable_import) и записи (pxfwritable_export)

DISTRIBUTED BY

При загрузке данных из таблицы Greengage DB во внешнюю пишущую таблицу рекомендуется указывать ту же политику распределения или имя столбца в обеих таблицах. Это позволит избежать дополнительного перемещения данных между сегментами при выполнении операции загрузки. Более подробную информацию о распределении таблиц можно получить в статье Распределение данных

<custom_option>

Одна из опций, описанных ниже, указываемая в строке LOCATION

SERVER=<server_name>

Имя конфигурации сервера, который используется для доступа к данным. Если опция опущена, используется конфигурация сервера с именем default

IGNORE_MISSING_PATH

Действие, которое необходимо выполнить, если <path_to_data> отсутствует или указан неверно. Если установлено значение false (по умолчанию), возвращается ошибка. Если установлено значение true, PXF игнорирует ошибку и возвращает пустой фрагмент. Применяется только для читающих внешних таблиц; в случае пишущих внешних таблиц игнорируется

COMPRESSION_CODEC

Кодек сжатия, используемый при записи данных: snappy, gzip, lzo или uncompressed (без сжатия).

Если сжатия данных не требуется, следует явно указать значение uncompressed. В противном случае выполняется сжатие с помощью кодека Snappy

ROWGROUP_SIZE

Размер (в байтах) группы строк, которая обеспечивает логическое разбиение данных на строки. Размер группы строк по умолчанию составляет 8 * 1024 * 1024 байт

PAGE_SIZE

Размер (в байтах) страницы, которая делит группы строк в столбце на фрагменты столбцов. Размер страницы по умолчанию составляет 1 * 1024 * 1024 байт

ENABLE_DICTIONARY

Указывает, следует ли включать словарное кодирование. Значение по умолчанию — true: словарное кодирование включено при записи файлов Parquet

DICTIONARY_PAGE_SIZE

Когда словарное кодирование включено, для каждого столбца в каждой группе строк определяется единая словарная страница. Параметр DICTIONARY_PAGE_SIZE аналогичен PAGE_SIZE, но задается специально для словаря. Размер словарной страницы по умолчанию составляет 1 * 1024 * 1024 байт

PARQUET_VERSION

Версия Parquet; поддерживаются значения v1 (по умолчанию) и v2

SCHEMA

Абсолютный путь к файлу схемы Parquet на хосте Greengage DB или в объектном хранилище. Если значение не указано, PXF создает схему на основе определения внешней таблицы

Условия переполнения числовых данных

Для записи числовых данных в формат данных Parquet через коннектор PXF используется класс HiveDecimal, в котором как точность, так и масштаб числового типа ограничены максимальным значением 38. При определении столбца внешней таблицы с типом NUMERIC без указания точности и масштаба PXF неявно сопоставляет столбец типу DECIMAL(38, 18).

PXF обрабатывает следующие условия переполнения числовых данных:

  • Столбец внешней таблицы определен с типом NUMERIC, при этом общее количество цифр значения превышает максимально допустимую точность в 38, например 1234567890123456789012345678901234567890.12345, в котором общее количество цифр — 45.

  • Столбец внешней таблицы определен с типом NUMERIC(<precision>) и точностью (<precision>), превышающей 38, например NUMERIC(55).

  • Столбец внешней таблицы определен с типом NUMERIC, при этом количество цифр в целой части значения превышает 20 (38-18), например 123456789012345678901234567890.12345, в котором количество цифр целой части — 30.

Если определяется столбец с типом NUMERIC(<precision>, <scale>), в котором количество цифр в целой части значения превышает величину <precision>-<scale>, PXF возвращает ошибку. Например, определен столбец NUMERIC(20,4) со значением 12345678901234567.12, в котором количество цифр целой части равно 17, что превышает 20-4=16.

При обнаружении переполнения числовых данных PXF выполняет одно из следующих действий: округляет значение (по умолчанию), возвращает ошибку или игнорирует переполнение. Выполняемое действие указывается с помощью свойства pxf.parquet.write.decimal.overflow конфигурационного файла pxf-site.xml сервера PXF.

Значение Действие PXF

round

Действие по умолчанию. При обнаружении переполнения PXF пытается округлить значение для соответствия требованиям точности и масштаба перед записью и возвращает ошибку, если округление не удалось. Это может потенциально привести к неполному набору данных во внешней системе

error

PXF возвращает ошибку при обнаружении переполнения, и транзакция прерывается

ignore

PXF возвращает предупреждение и пытается округлить значение для соответствия требованиям точности и масштаба; если округление не удалось, записывается значение NULL

ПРИМЕЧАНИЕ

Подробная информация о конфигурировании сервера PXF приведена в статье Настройка PXF-сервера документации PXF.

Примеры

Эти примеры демонстрируют настройку и использование коннектора PXF object store для чтения и записи данных Parquet в объектном хранилище с помощью внешних таблиц.

Предварительные требования

Для выполнения практических примеров подключитесь к мастер-хосту Greengage DB как gpadmin с помощью psql, как описано в статье Подключение к Greengage DB с использованием psql. Затем создайте тестовую базу данных customers и подключитесь к ней:

DROP DATABASE IF EXISTS customers;
CREATE DATABASE customers;
\c customers

Чтобы создать внешнюю таблицу с использованием протокола PXF, предварительно зарегистрируйте в БД расширение PXF, как описано в разделе Регистрация PXF в БД документации PXF:

CREATE EXTENSION pxf;

Конфигурирование коннектора PXF S3

Для того чтобы подключиться к объектному хранилищу с помощью PXF, необходимо создать соответствующую конфигурацию сервера, а затем синхронизировать конфигурацию между хостами кластера Greengage DB:

  1. На мастер-хосте Greengage DB войдите под пользователем gpadmin.

  2. Перейдите в каталог $PXF_BASE/servers и создайте каталог конфигурации сервера S3 с именем s3. Скопируйте необходимый для используемого объектного хранилища файл конфигурации сервера из $PXF_HOME/templates в $PXF_BASE/servers/s3. В примере используется файл конфигурации на основе шаблона minio-site.xml.

    $ mkdir $PXF_BASE/servers/s3
    $ cd $PXF_BASE/servers/s3
    $ cp $PXF_HOME/templates/minio-site.xml .

    В файле конфигурации укажите необходимые данные для подключения к объектному хранилищу:

    <?xml version="1.0" encoding="UTF-8"?>
    <configuration>
        <property>
            <name>fs.s3a.endpoint</name>
            <value>storage.example.com</value>
        </property>
        <property>
            <name>fs.s3a.access.key</name>
            <value>${ACCESS_KEY}</value>
        </property>
        <property>
            <name>fs.s3a.secret.key</name>
            <value>${SECRET_KEY}</value>
        </property>
        <property>
            <name>fs.s3a.fast.upload</name>
            <value>true</value>
        </property>
        <property>
            <name>fs.s3a.path.style.access</name>
            <value>true</value>
        </property>
    </configuration>
    ПРИМЕЧАНИЕ

    Обратите внимание, что учетные данные для подключения к объектному хранилищу указываются в виде переменных окружения ACCESS_KEY и SECRET_KEY.

    Установить значения этих переменных можно следующим образом:

    $ export ACCESS_KEY=<access_key>
    $ export SECRET_KEY=<secret_key>

    Учетные данные в файле конфигурации можно указать и в виде обычного текста, но в целях безопасности рекомендуется использовать переменные окружения.

  3. Синхронизируйте конфигурацию между хостами кластера Greengage DB:

    $ pxf cluster sync

Создание пишущей внешней таблицы

  1. На мастер-хосте Greengage DB создайте пишущую внешнюю таблицу, сохраняющую данные в бакет customers на хосте S3. В выражении LOCATION укажите PXF-профиль s3:parquet и конфигурацию сервера. В выражении FORMAT укажите pxfwritable_export — встроенную кастомную функцию форматирования для операций записи:

    CREATE WRITABLE EXTERNAL TABLE customers_w (
            id INT,
            name TEXT, 
            ordered_items TEXT[]    
        )
        LOCATION ('pxf://customers?PROFILE=s3:parquet&SERVER=s3')
        FORMAT 'CUSTOM' (FORMATTER='pxfwritable_export');
  2. Вставьте тестовые данные в таблицу customers_w:

    INSERT INTO customers_w 
    VALUES (1, 'John Doe', ARRAY['laptop', 'monitor']),
           (2, 'Jane Smith', ARRAY['keyboard', 'mouse', 'pad']),
           (3, 'Bob Brown', ARRAY['headphones']),
           (4, 'Alice Green', ARRAY['webcam', 'microphone']);
  3. Проверьте файлы, созданные в бакете customers на хосте S3. Набор файлов должен выглядеть подобным образом:

    202-0000000013_0.snappy.parquet
    202-0000000013_3.snappy.parquet

Создание читающей внешней таблицы

  1. На мастер-хосте Greengage DB создайте внешнюю таблицу, ссылающуюся на файлы из бакета customers на хосте S3. В выражении LOCATION укажите PXF-профиль s3:parquet и конфигурацию сервера. В выражении FORMAT укажите pxfwritable_import — встроенную кастомную функцию форматирования для операций чтения:

    CREATE EXTERNAL TABLE customers_r (
            id INT,
            name TEXT, 
            ordered_items TEXT[]
        )
        LOCATION('pxf://customers?PROFILE=s3:parquet&SERVER=s3')
        FORMAT 'CUSTOM' (FORMATTER='pxfwritable_import');
  2. Выполните запрос к созданной внешней таблице:

    SELECT * FROM customers_r;

    Вывод должен выглядеть следующим образом:

     id |    name     |    ordered_items
    ----+-------------+----------------------
      1 | John Doe    | {laptop,monitor}
      3 | Bob Brown   | {headphones}
      4 | Alice Green | {webcam,microphone}
      2 | Jane Smith  | {keyboard,mouse,pad}
    (4 rows)