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!" を使用します。

  • デフォルトスキーマにユーザーテーブルを作成するには、次のコードを使用します。

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=true および kudu.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=true および kudu.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 列のハッシュ値によって5つのパーティションに分割され、number_of_replicas は明示的に3に設定されています。

プライマリキー列は、常に列リストの最初の列である必要があります。パーティションで使用されるすべての列は、プライマリキーの一部である必要があります。

テーブルプロパティ number_of_replicas はオプションです。これは、タブレットレプリカの数を定義し、奇数でなければなりません。指定しない場合は、Kuduマスター構成からのデフォルトのレプリケーションファクターが使用されます。

Kuduは、ハッシュパーティショニングとレンジパーティショニングの2種類のパーティショニングをサポートしています。ハッシュパーティショニングは、ハッシュ値によって行を複数のバケットのいずれかに分散します。レンジパーティションは、完全に順序付けられたレンジパーティションキーを使用して行を分散します。具体的なレンジパーティションは明示的に作成する必要があります。Kuduは、マルチレベルパーティショニングもサポートしています。テーブルには、少なくとも1つのパーティショニング(ハッシュまたはレンジのいずれか)が必要です。最大で1つのレンジパーティショニングを持つことができますが、複数のハッシュパーティショニング「レベル」を持つことができます。

詳細については、「パーティショニングの設計」を参照してください。

列のプロパティ

列の名前と型に加えて、列のプロパティをさらにいくつか指定できます。

列のプロパティ名

タイプ

説明

primary_key

BOOLEAN

trueの場合、列はプライマリキー列に属します。Kuduプライマリキーは、一意性制約を強制します。同じプライマリキーを持つ2番目の行を挿入すると、既存の行が更新されます(「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 (...);

パーティショニングの設計

テーブルには、少なくとも1つのパーティショニング(ハッシュまたはレンジのいずれか)が必要です。最大で1つのレンジパーティショニングを持つことができますが、複数のハッシュパーティショニング「レベル」を持つことができます。詳細については、Apache Kuduドキュメントの「パーティショニング」を参照してください。

PrestoでKuduテーブルを作成する場合、パーティショニング設計はいくつかのテーブルプロパティによって指定されます。

ハッシュパーティショニング

最初のハッシュパーティショングループを2つのテーブルプロパティで指定できます

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
)

これは、col1 および col2 列を使用したハッシュパーティショニングを定義し、4つのパーティションに分散します。

2つの別個のハッシュパーティショングループを定義するには、partition_by_second_hash_columnspartition_by_second_hash_buckets という名前の2番目のテーブルプロパティのペアも使用します。

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 列を使用した2番目のハッシュパーティショングループを3つのバケットに分散した、2レベルのハッシュパーティショニングを定義します。結果として、2 x 3 = 6個のパーティションを持つテーブルができます。

レンジパーティショニング

Apache Kuduでは、最大1つのレンジパーティショニングを指定できます。列は、テーブルプロパティ 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}]'
)

これは、2つのハッシュパーティショングループと、event_time 列での1つのレンジパーティショニングを使用した、3レベルのパーティショニングを定義します。「2018-01-01T00:00:00」で分割された2つのレンジパーティションが作成されます。

テーブルプロパティ 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 列のレンジパーティションを持つテーブルが作成されます。さらに、3つのレンジパーティションが作成されます。

  1. 2017年より前のすべてのevent_time(下限= null は、境界がないことを意味します)

  2. 2017年の前半

  3. 2017年の後半

これは、2018年以降の event_time を持つ行を追加しようとすると、パーティションが定義されていないため失敗することを意味します。次のセクションでは、既存のテーブルの新しいレンジパーティションを定義する方法を示します。

レンジパーティションの管理

既存のテーブルには、レンジパーティションを追加および削除するプロシージャがあります。

  • レンジパーティションの追加

    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>: 範囲パーティションの下限と上限を、'{"lower": <value>, "upper": <value>}' の形式のjson文字列として、または範囲パーティションに複数の列がある場合は、 '{"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クラスターの使用はテストされていません。