读写HDFS Parquet数据

使用PXF HDFS连接器读写Parquet格式数据。本节介绍如何读写以Parquet格式存储的HDFS文件,包括如何创建、查询和写入引用HDFS文件的外部表。

PXF当前仅支持读写基本Parquet数据类型。

PXF Parquet写入支持是一个Beta功能。

先决条件

在尝试从HDFS读取或向HDFS写入数据之前,请确保已满足PXF Hadoop先决条件

数据类型映射

要在Greenplum数据库中读写Parquet基本数据类型,请将Parquet数据值映射到相同类型的Greenplum数据库列。下表总结了外部映射规则:

Parquet数据类型 PXF/Greenplum数据类型
boolean Boolean
byte_array Bytea, Text
double Float8
fixed_len_byte_array Numeric
float Real
int_8, int_16 Smallint, Integer
int64 Bigint
int96 Timestamp, Timestamptz
写入Parquet时:
  • PXF将timestamp本地化为当前系统时区,并将其转换为通用时间(UTC),然后最终转换为int96
  • PXF将timestamp转换为UTCtimestamp,然后转换为int96。在此转换过程中,PXF会丢失时区信息。

创建外部表

PXF HDFS连接器hdfs:parquet配置文件支持读写Parquet格式的HDFS数据。当您将记录插入可写外部表中时,您插入的数据块将写入指定目录中一个或多个文件。

使用以下语法创建引用HDFS目录的Greenplum数据库外部表:

CREATE [WRITABLE] EXTERNAL TABLE <table_name>
    ( <column_name> <data_type> [, ...] | LIKE <other_table> )
LOCATION ('pxf://<path-to-hdfs-dir>
    ?PROFILE=hdfs:parquet[&SERVER=<server_name>][&<custom-option>=<value>[...]]')
FORMAT 'CUSTOM' (FORMATTER='pxfwritable_import'|'pxfwritable_export');
[DISTRIBUTED BY (<column_name> [, ... ] ) | DISTRIBUTED RANDOMLY];

CREATE EXTERNAL TABLE命令中使用的特定关键字和值见下表中描述。

关键字
<path‑to‑hdfs‑file> HDFS数据存储中目录或文件的绝对路径
PROFILE PROFILE关键字必须指定为hdfs:parquet
SERVER=<server_name> PXF用于访问数据的命名服务器配置。可选的; 如果未指定,PXF将使用default服务器。
<custom‑option>=<value> <custom-option>描述见下方
FORMAT ‘CUSTOM’ 使用FORMATCUSTOM'时指定(FORMATTER='pxfwritable_export') (写入) 或 (FORMATTER='pxfwritable_import') (读取)。
DISTRIBUTED BY 如果您计划将现有Greenplum数据库表中的数据加载到可写外部表,考虑在可写外部表上使用与Greenplum表相同的分布策略或<字段名>。 这样做可以避免数据加载操作中segment节点间额外的数据移动。

PXF hdfs:parquet 配置文件支持与编码和压缩有关的写入选项。您可以在CREATE WRITABLE EXTERNAL TABLE LOCATION子句中指定这些写入选项。hdfs:parquet配置文件支持以下自定义选项:

写入选项 值描述
COMPRESSION_CODEC 压缩编码器别名。 用于写入Parquet数据受支持的压缩编码器包括: snappy, gzip, lzo, 和uncompressed。 如果未提供此选项,PXF将使用snappy压缩编码器来压缩数据。
ROWGROUP_SIZE Parquet文件由一个或多个行组组成,将数据逻辑划分为行。ROWGROUP_SIZE 标识行组的大小(以字节为单位)。默认的行组大小为8 * 1024 * 1024字节。
PAGE_SIZE 行组由划分为页面的列块组成。PAGE_SIZE是此类页面的大小(以字节为单位)。默认的页面大小为1024 * 1024字节。
DICTIONARY_PAGE_SIZE 当PXF写入Parquet文件时,默认情况下启用字典编码。每列、每行组只有一个字典页面。DICTIONARY_PAGE_SIZEPAGE_SIZE类似,但是对于字典而言:默认字典页面大小为512 * 1024字节。
PARQUET_VERSION Parquet版本;支持v1v2。默认的Parquet版本为v1

注意: 如果您不希望PXF压缩数据,则必须明确指定uncompressed

使用PXF写入HDFS的Parquet文件具有以下命名格式:<file>.<compress_extension>.parquet,例如 1547061635-0000004417_0.gz.parquet.

示例

本示例采用在示例:读取HDFS中的文本数据中介绍的数据模式。

列名 数据类型
location text
month text
number_of_orders int
total_sales float8

在此示例中,您创建一个Parquet格式的可写外部表,该表使用默认的PXF服务器引用HDFS中的Parquet格式的数据,将一些数据插入表中,然后创建一个可读外部表以读取数据。

  1. 使用hdfs:parquet配置文件创建一个可写外部表。例如:

    postgres=# CREATE WRITABLE EXTERNAL TABLE pxf_tbl_parquet (location text, month text, number_of_orders int, total_sales double precision)
        LOCATION ('pxf://data/pxf_examples/pxf_parquet?PROFILE=hdfs:parquet')
      FORMAT 'CUSTOM' (FORMATTER='pxfwritable_export');
    
  2. 通过直接写入pxf_tbl_parquet表将一些记录写入HDFS的pxf_parquet目录中。例如:

    postgres=# INSERT INTO pxf_tbl_parquet VALUES ( 'Frankfurt', 'Mar', 777, 3956.98 );
    postgres=# INSERT INTO pxf_tbl_parquet VALUES ( 'Cleveland', 'Oct', 3812, 96645.37 );
    
  3. 回想一下,Greenplum 数据库不支持直接查询一个可写外部表。要读取pxf_parquet中的数据,请创建一个引用此HDFS目录的可读外部表:

    postgres=# CREATE EXTERNAL TABLE read_pxf_parquet(location text, month text, number_of_orders int, total_sales double precision)
        LOCATION ('pxf://data/pxf_examples/pxf_parquet?PROFILE=hdfs:parquet')
        FORMAT 'CUSTOM' (FORMATTER='pxfwritable_import');
    
  4. 查询可读外部表read_pxf_parquet

    postgres=# SELECT * FROM read_pxf_parquet ORDER BY total_sales;
    
     location  | month | number_of_orders | total_sales
    -----------+-------+------------------+-------------
     Frankfurt | Mar   |              777 |     3956.98
     Cleveland | Oct   |             3812 |     96645.4
    (2 rows)