Kudu 连接器

Kudu 连接器允许查询、插入和删除数据 Apache Kudu

兼容性

连接器与所有从 1.0 开始的 Apache Kudu 版本兼容。

如果连接器使用目标服务器上不可用的功能,则会返回错误。目前使用 Apache Kudu 1.8.0 进行测试。

配置

要配置 Kudu 连接器,请创建一个目录属性文件 etc/catalog/kudu.properties,其中包含以下内容,并根据需要替换属性

connector.name=kudu

## List of Kudu master addresses, at least one is needed (comma separated)
## Supported formats: example.com, example.com:7051, 192.0.2.1, 192.0.2.1:7051,
##                    [2001:db8::1], [2001:db8::1]:7051, 2001:db8::1
kudu.client.master-addresses=localhost

## Kudu does not support schemas, but the connector can emulate them optionally.
## By default, this feature is disabled, and all tables belong to the default schema.
## For more details see connector documentation.
#kudu.schema-emulation.enabled=false

## Prefix to use for schema emulation (only relevant if `kudu.schema-emulation.enabled=true`)
## The standard prefix is `presto::`. Empty prefix is also supported.
## For more details see connector documentation.
#kudu.schema-emulation.prefix=

#######################
### Advanced Kudu Java client configuration
#######################

## Default timeout used for administrative operations (e.g. createTable, deleteTable, etc.)
#kudu.client.default-admin-operation-timeout = 30s

## Default timeout used for user operations
#kudu.client.default-operation-timeout = 30s

## Default timeout to use when waiting on data from a socket
#kudu.client.default-socket-read-timeout = 10s

## Disable Kudu client's collection of statistics.
#kudu.client.disable-statistics = false

查询数据

Apache Kudu 不支持模式,即表名称空间。连接器可以通过表命名约定来模拟模式。

默认行为 (无模式模拟)

默认情况下禁用模式模拟。在这种情况下,所有 Kudu 表都属于 default 模式。

例如,名为 orders 的 Kudu 表可以在 Presto 中使用 SELECT * FROM kudu.default.orders 查询,如果目录和模式分别设置为 kududefault,也可以简单地使用 SELECT * FROM orders 查询。

表名可以在 Kudu 中包含任何字符。在这种情况下,请使用双引号。例如,要查询名为 special.table! 的 Kudu 表,请使用 SELECT * FROM kudu.default."special.table!"

示例

  • 在默认模式下创建一个 users 表,使用

CREATE TABLE kudu.default.users (
  user_id int WITH (primary_key = true),
  first_name varchar,
  last_name varchar
) WITH (
  partition_by_hash_columns = ARRAY['user_id'],
  partition_by_hash_buckets = 2
);

在创建 Kudu 表时,您必须/可以指定有关主键、编码和列压缩以及哈希或范围分区的其他信息。详细信息请参见 创建表 部分。

  • 可以使用以下命令描述表

DESCRIBE kudu.default.users;

您应该得到类似以下的结果

   Column   |  Type   |                      Extra                      | Comment
------------+---------+-------------------------------------------------+---------
 user_id    | integer | primary_key, encoding=auto, compression=default |
 first_name | varchar | nullable, encoding=auto, compression=default    |
 last_name  | varchar | nullable, encoding=auto, compression=default    |
(3 rows)
  • 使用以下命令插入一些数据

INSERT INTO kudu.default.users VALUES (1, 'Donald', 'Duck'), (2, 'Mickey', 'Mouse');
  • 选择插入的数据

SELECT * FROM kudu.default.users;

使用模式模拟的行为

如果在连接器属性中启用了模式模拟,即 etc/catalog/kudu.properties,则表将根据某些约定映射到模式。

  • 使用 kudu.schema-emulation.enabled=truekudu.schema-emulation.prefix=,映射方式如下

    Kudu 表名

    Presto 限定名

    orders

    kudu.default.orders

    part1.part2

    kudu.part1.part2

    x.y.z

    kudu.x."y.z"

    由于 Kudu 不直接支持模式,因此创建了一个名为 $schemas 的特殊表来管理模式。

  • 使用 kudu.schema-emulation.enabled=truekudu.schema-emulation.prefix=presto::,映射方式如下

    Kudu 表名

    Presto 限定名

    orders

    kudu.default.orders

    part1.part2

    kudu.default."part1.part2"

    x.y.z

    kudu.default."x.y.z"

    presto::part1.part2

    kudu.part1.part2

    presto:x.y.z

    kudu.x."y.z"

    由于 Kudu 不直接支持模式,因此创建了一个名为 presto::$schemas 的特殊表来管理模式。

数据类型映射

Presto 和 Kudu 的数据类型尽可能地映射

Presto 数据类型

Kudu 数据类型

注释

BOOLEAN

BOOL

TINYINT

INT8

SMALLINT

INT16

INTEGER

INT32

BIGINT

INT64

REAL

FLOAT

DOUBLE

DOUBLE

VARCHAR

STRING

[1]

VARBINARY

BINARY

[1]

TIMESTAMP

UNIXTIME_MICROS

Kudu 列中的 µs 分辨率降低到 ms 分辨率

DECIMAL

DECIMAL

仅支持 Kudu 服务器 >= 1.7.0

CHAR

-

不支持

DATE

-

不支持 [2]

TIME

-

不支持

JSON

-

不支持

TIME WITH TIMEZONE

-

不支持

TIMESTAMP WITH TIME ZONE

-

不支持

INTERVAL YEAR TO MO NTH

-

不支持

INTERVAL DAY TO SEC OND

-

不支持

ARRAY

-

不支持

MAP

-

不支持

IPADDRESS

-

不支持

支持的 Presto SQL 语句

Presto SQL 语句

注释

SELECT

INSERT INTO ... VALUES

类似于 upsert 的行为

INSERT INTO ... SELECT ...

类似于 upsert 的行为

DELETE

CREATE SCHEMA

仅在启用模式模拟时允许

DROP SCHEMA

仅在启用模式模拟时允许

CREATE TABLE

创建表

CREATE TABLE ... AS

DROP TABLE

ALTER TABLE ... RENAME TO ...

ALTER TABLE ... RENAME COLUMN ...

仅在不是主键的一部分时允许

ALTER TABLE ... ADD COLUMN ...

添加列

ALTER TABLE ... DROP COLUMN ...

仅在不是主键的一部分时允许

SHOW SCHEMAS

SHOW TABLES

SHOW CREATE TABLE

SHOW COLUMNS FROM

DESCRIBE

SHOW COLUMNS FROM 相同

CALL kudu.system.add_range_partition

将范围分区添加到表中。见 管理范围分区

CALL kudu.system.drop_range_partition

从表中删除一个范围分区。参见 管理范围分区

ALTER SCHEMA ... RENAME TO ... 不支持。

创建表

创建 Kudu 表时,您需要提供列及其类型,当然,Kudu 还需要有关分区的信息,以及可选的列编码和压缩信息。

简单示例

CREATE TABLE user_events (
  user_id int WITH (primary_key = true),
  event_name varchar WITH (primary_key = true),
  message varchar,
  details varchar WITH (nullable = true, encoding = 'plain')
) WITH (
  partition_by_hash_columns = ARRAY['user_id'],
  partition_by_hash_buckets = 5,
  number_of_replicas = 3
);

主键由 user_idevent_name 组成,表根据 user_id 列的哈希值分成五个分区,并且 number_of_replicas 显式设置为 3。

主键列必须始终是列列表中的第一列。所有用于分区的列都必须是主键的一部分。

表属性 number_of_replicas 是可选的。它定义了数据块副本的数量,并且必须是奇数。如果没有指定,则使用 Kudu 主配置中的默认复制因子。

Kudu 支持两种不同的分区类型:哈希分区和范围分区。哈希分区通过哈希值将行分配到多个桶中的一个。范围分区使用完全有序的范围分区键来分配行。具体的范围分区必须显式创建。Kudu 还支持多级分区。表必须至少有一个分区(哈希或范围)。它最多只能有一个范围分区,但可以有多个哈希分区“级别”。

有关更多详细信息,请参阅 分区设计

列属性

除了列名和类型之外,您还可以指定列的更多属性。

列属性名称

类型

描述

primary_key

BOOLEAN

如果为 true,则该列属于主键列。Kudu 主键强制执行唯一性约束。插入具有相同主键的第二行会导致更新现有行(“UPSERT”)。另请参阅 Kudu 文档中的 主键设计

nullable

BOOLEAN

如果为 true,则该值可以为 null。主键列不能为 null。

encoding

VARCHAR

列编码可以帮助节省存储空间并提高查询性能。如果未指定,Kudu 将根据列类型使用自动编码。有效值为:'auto''plain''bitshuffle''runlength''prefix''dictionary''group_varint'。另请参阅 Kudu 文档中的 列编码

compression

VARCHAR

编码后的列值可以进行压缩。如果未指定,Kudu 将使用默认压缩。有效值为:'default''no''lz4''snappy''zlib'。另请参阅 Kudu 文档中的 列压缩

示例

CREATE TABLE mytable (
  name varchar WITH (primary_key = true, encoding = 'dictionary', compression = 'snappy'),
  index bigint WITH (nullable = true, encoding = 'runlength', compression = 'lz4'),
  comment varchar WITH (nullable = true, encoding = 'plain', compression = 'default'),
   ...
) WITH (...);

分区设计

表必须至少有一个分区(哈希或范围)。它最多只能有一个范围分区,但可以有多个哈希分区“级别”。有关更多详细信息,请参阅 Apache Kudu 文档:分区

如果您在 Presto 中创建 Kudu 表,则分区设计由多个表属性给出。

哈希分区

您可以使用两个表属性提供第一个哈希分区组

partition_by_hash_columns 定义属于分区组的列,而 partition_by_hash_buckets 定义将哈希值范围划分的分区数量。所有分区列都必须是主键的一部分。

示例

CREATE TABLE mytable (
  col1 varchar WITH (primary_key=true),
  col2 varchar WITH (primary_key=true),
  ...
) WITH (
  partition_by_hash_columns = ARRAY['col1', 'col2'],
  partition_by_hash_buckets = 4
)

这定义了一个哈希分区,其中 col1col2 列分布在 4 个分区上。

要定义两个单独的哈希分区组,还需要使用第二对表属性,分别称为 partition_by_second_hash_columnspartition_by_second_hash_buckets

示例

CREATE TABLE mytable (
  col1 varchar WITH (primary_key=true),
  col2 varchar WITH (primary_key=true),
  ...
) WITH (
  partition_by_hash_columns = ARRAY['col1'],
  partition_by_hash_buckets = 2,
  partition_by_second_hash_columns = ARRAY['col2'],
  partition_by_second_hash_buckets = 3
)

这定义了一个两级哈希分区,第一个哈希分区组包含 col1 列,分布在 2 个桶中,第二个哈希分区组包含 col2 列,分布在 3 个桶中。结果是,您的表将包含 2 x 3 = 6 个分区。

范围分区

您可以在 Apache Kudu 中最多提供一个范围分区。列通过表属性 partition_by_range_columns 定义。范围本身是在创建表时通过表属性 range_partitions 给出的。或者,可以使用 kudu.system.add_range_partitionkudu.system.drop_range_partition 过程来管理现有表的范围分区。两种方式的详细信息见下文。

示例

CREATE TABLE events (
  rack varchar WITH (primary_key=true),
  machine varchar WITH (primary_key=true),
  event_time timestamp WITH (primary_key=true),
  ...
) WITH (
  partition_by_hash_columns = ARRAY['rack'],
  partition_by_hash_buckets = 2,
  partition_by_second_hash_columns = ARRAY['machine'],
  partition_by_second_hash_buckets = 3,
  partition_by_range_columns = ARRAY['event_time'],
  range_partitions = '[{"lower": null, "upper": "2018-01-01T00:00:00"}, {"lower": "2018-01-01T00:00:00", "upper": null}]'
)

这定义了一个三级分区,其中包含两个哈希分区组,以及一个在 event_time 列上的范围分区。在“2018-01-01T00:00:00”处创建了两个范围分区。

表属性 range_partitions

使用 range_partitions 表属性,您可以指定要创建的具体范围分区。范围分区定义本身必须在表属性 partition_design 中单独给出。

示例

CREATE TABLE events (
  serialno varchar WITH (primary_key = true),
  event_time timestamp WITH (primary_key = true),
  message varchar
) WITH (
  partition_by_hash_columns = ARRAY['serialno'],
  partition_by_hash_buckets = 4,
  partition_by_range_columns = ARRAY['event_time'],
  range_partitions = '[{"lower": null, "upper": "2017-01-01T00:00:00"},
                       {"lower": "2017-01-01T00:00:00", "upper": "2017-07-01T00:00:00"},
                       {"lower": "2017-07-01T00:00:00", "upper": "2018-01-01T00:00:00"}]'
);

这将在 serialno 列上创建具有 4 个桶的哈希分区,并在 event_time 列上创建范围分区。此外,还创建了三个范围分区

  1. 对于所有事件时间在 2017 年之前的事件时间(下限 = null 表示它没有限制)

  2. 对于 2017 年上半年

  3. 对于 2017 年下半年

这意味着任何尝试添加事件时间为 2018 年或之后的行的尝试都会失败,因为没有定义分区。下一节将介绍如何为现有表定义新的范围分区。

管理范围分区

对于现有表,可以使用过程来添加和删除范围分区。

  • 添加范围分区

    CALL kudu.system.add_range_partition(<schema>, <table>, <range_partition_as_json_string>),
    
  • 删除范围分区

    CALL kudu.system.drop_range_partition(<schema>, <table>, <range_partition_as_json_string>)
    
    • <schema>:表的模式

    • <table>:表名称

    • <range_partition_as_json_string>:范围分区的下限和上限,以 JSON 字符串的形式给出,格式为 '{"lower": <value>, "upper": <value>}',或者如果范围分区具有多个列,则为:'{"lower": [<value_col1>,...], "upper": [<value_col1>,...]}'。下限和上限值的具体文字取决于列类型。

      示例

      Presto 数据类型

      JSON 字符串示例

      BIGINT

      ‘{“lower”: 0, “upper”: 1000000}’

      SMALLINT

      ‘{“lower”: 10, “upper”: null}’

      VARCHAR

      ‘{“lower”: “A”, “upper”: “M”}’

      TIMESTAMP

      ‘{“lower”: “2018-02-01T00:00:00.000”, “upper”: “2018-02-01T12:00:00.000”}’

      BOOLEAN

      ‘{“lower”: false, “upper”: true}’

      VARBINARY

      以 base64 字符串形式编码的值

      要指定无界限,请使用值 null

示例

CALL kudu.system.add_range_partition('myschema', 'events', '{"lower": "2018-01-01", "upper": "2018-06-01"}')

这将为 myschema 模式中的表 events 添加一个范围分区,下限为 2018-01-01(更准确地说,为 2018-01-01T00:00:00.000),上限为 2018-07-01

使用 SQL 语句 SHOW CREATE TABLE 来查询现有的范围分区(它们显示在表属性 range_partitions 中)。

添加列

将列添加到现有表使用 SQL 语句 ALTER TABLE ... ADD COLUMN ...。您可以指定与创建表时相同的列属性。

示例

ALTER TABLE mytable ADD COLUMN extraInfo varchar WITH (nullable = true, encoding = 'plain')

另请参阅 列属性

已知限制

  • Kudu 中只支持小写表名和列名

  • 使用安全的 Kudu 集群尚未经过测试。