The Kudu connector lets you query, insert, and delete data stored in Apache Kudu tables.
Background information
The Kudu connector covers the following topics:
Prerequisites
A Trino cluster and a Hadoop cluster with the Kudu service are created. For more information, see Create a cluster.
Limitations
-
Kudu 1.10 or later.
-
Network connectivity between the Trino and Hadoop clusters.
-
Kudu table and column names must be lowercase.
Modify the Kudu connector configuration
For more information, see Configure connectors.
In the E-MapReduce (EMR) console, go to the Configure page of the Trino service. In the Service Configuration area, click the kudu.properties tab.
|
Parameter |
Description |
|
kudu.client.master-addresses |
A comma-separated list of Kudu master addresses. The following formats are supported: example.com, example.com:7051, 192.0.2.1, 192.0.2.1:7051, [2001:db8::1], [2001:db8::1]:7051, and 2001:db8::1. Default value: localhost. Note
To write data to and query data from Kudu tables, change the default value from localhost to the IP address or hostname of the Kudu master node, for example, master-1-1. |
|
kudu.schema-emulation.enabled |
Whether to enable schema emulation.
Important
To add this item, click Add Configuration Item on the kudu.properties tab. For instructions, see Add configuration items. |
|
kudu.schema-emulation.prefix |
The prefix for schema emulation. Important
This configuration item is required when The standard prefix is |
|
kudu.client.default-admin-operation-timeout |
The default timeout for administrative operations, such as Create Table and Delete Table. Default value: 30s. |
|
kudu.client.default-operation-timeout |
The default timeout for user operations. Default value: 30s. |
|
kudu.client.default-socket-read-timeout |
The default timeout for waiting for data from a socket. Default value: 10s. |
|
kudu.client.disable-statistics |
Whether to disable Kudu client statistics collection.
|
Query data
Apache Kudu does not support schemas. However, you can configure the Kudu connector to emulate them.
Schema emulation disabled (default)
By default, schema emulation is disabled. In this case, all Kudu tables are in the default schema.
For example, to query the orders table, run SELECT * FROM kudu.default.orders. If the catalog and schema are set to kudu and default respectively, you can simplify the query to SELECT * FROM orders.
Kudu table names can contain any characters. If a name contains special characters, you must enclose it in double quotes ("). For example, to query the special.table! table, run SELECT * FROM kudu.default."special.table!".
Examples:
-
Create a
userstable in thedefaultschema.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 );NoteWhen you create a table, you must specify required information, such as the primary key, column encoding and compression formats, and hash or range partitions.
-
View the table information.
DESCRIBE kudu.default.users;The command returns output similar to the following:
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 data.
INSERT INTO kudu.default.users VALUES (1, 'Donald', 'Duck'), (2, 'Mickey', 'Mouse'); -
Query the data.
SELECT * FROM kudu.default.users;
Schema emulation enabled
If you enable schema emulation in the connector's configuration file (etc/catalog/kudu.properties), tables are mapped to schemas based on a naming convention.
-
If you set
kudu.schema-emulation.enabled=trueandkudu.schema-emulation.prefix=, tables are mapped as follows:Kudu table name
Presto table name
orderskudu.default.orderspart1.part2kudu.part1.part2x.y.zkudu.x."y.z"NoteBecause Kudu does not natively support schemas, Presto creates a special table named
$schemasto manage them. -
If you set
kudu.schema-emulation.enabled=trueandkudu.schema-emulation.prefix=presto::, tables are mapped as follows:Kudu table name
Presto table name
orderskudu.default.orderspart1.part2kudu.default."part1.part2"x.y.zkudu.default."x.y.z"presto::part1.part2kudu.part1.part2presto::x.y.zkudu.x."y.z"NoteBecause Kudu does not natively support schemas, Presto creates a special table named
presto::$schemasto manage them.
Data type mapping
The following table lists the data type mappings between Presto and Kudu.
|
Presto type |
Kudu type |
Remarks |
|
BOOLEAN |
BOOL |
N/A |
|
TINYINT |
INT8 |
|
|
SMALLINT |
INT16 |
|
|
INTEGER |
INT32 |
|
|
BIGINT |
INT64 |
|
|
REAL |
FLOAT |
|
|
DOUBLE |
DOUBLE |
|
|
VARCHAR |
STRING |
When you create a Kudu table from a Presto table with a |
|
VARBINARY |
BINARY |
|
|
TIMESTAMP |
UNIXTIME_MICROS |
This mapping reduces the precision of the Kudu column from microseconds (µs) to milliseconds (ms). |
|
DECIMAL |
DECIMAL |
Supported only by Kudu 1.7.0 and later. |
|
DATE |
N/A |
Unsupported. When you create a Kudu table from a Presto table with a |
|
CHAR |
N/A |
Unsupported. |
|
TIME |
||
|
JSON |
||
|
TIME WITH TIME ZONE |
||
|
TIMESTAMP WITH TIME ZONE |
||
|
INTERVAL YEAR TO MONTH |
||
|
INTERVAL DAY TO SECOND |
||
|
ARRAY |
||
|
MAP |
||
|
IPADDRESS |
Supported Presto SQL statements
The ALTER SCHEMA ... RENAME TO ... statement is not supported.
|
Statement |
Description |
|
|
None. |
|
|
None. |
|
|
None. |
|
|
None. |
|
|
Available only when schema emulation is enabled. |
|
|
Available only when schema emulation is enabled. |
|
|
Creates a table. For details, see Create a table. |
|
|
None. |
|
|
None. |
|
|
None. |
|
|
Adds a column. For details, see Add a column. |
|
|
These statements apply only to columns that are not part of the primary key. |
|
|
|
|
|
None. |
|
|
None. |
|
|
None. |
|
|
None. |
|
|
This statement is equivalent to |
|
|
Adds a range partition. For details, see Range partitions. |
|
|
Drops a range partition. For details, see Range partitions. |
Create a table
To create a table, specify its columns, data types, and partition information. You can also specify other details, such as the column encoding format or compression format. The following is an example.
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
);
In this example, the primary key consists of the user_id and event_name columns. The table is divided into five partitions based on the hash values of the user_id column. The number_of_replicas is set to 3.
When creating a table, note the following:
-
Primary key columns must be listed first. Partition key columns must be a subset of the primary key columns.
-
number_of_replicas: The number of tablet replicas, which must be an odd number. If unspecified, the default from the Kudu Master configuration is used. -
Kudu supports hash and range partitions. A hash partition distributes rows into buckets based on a hash value. A range partition distributes rows based on an ordered range partition key, and its specific ranges must be created explicitly. Kudu supports multi-level partitioning. A table must have at least one hash or range partition. It can have multiple hash partitions but at most one range partition.
Column properties
You can specify the following column properties in addition to the column name and data type.
|
Parameter |
Type |
Description |
|
primary_key |
BOOLEAN |
If true, this column is part of the primary key. A Kudu primary key enforces a uniqueness constraint. If you insert a row with a primary key that already exists, the existing row is updated. For more information, see Primary Key Design. |
|
nullable |
BOOLEAN |
If true, the column can be null. Important
Primary key columns cannot be null. |
|
encoding |
VARCHAR |
The column encoding format, which reduces storage and improves query performance. If not specified, Kudu automatically selects an encoding based on the column data type. Valid values: auto, plain, bitshuffle, runlength, prefix, dictionary, and group_varint. For more information, see Column Encoding. |
|
compression |
VARCHAR |
The column compression format. If not specified, Kudu uses the default compression format. Valid values: |
The following is an example:
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 (...);
Partition design
This section describes how to define hash and range partitions.
-
Hash partition
-
Defining one partition group
Use the partition_by_hash_columns and
partition_by_hash_bucketstable properties to specify the partition key columns and the number of partitions, respectively. All partition key columns must be a subset of the primary key columns. The following is an example: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 )NoteThis example defines a hash partition on the
col1andcol2columns and distributes the data into four partitions. -
Defining two partition groups
To define two independent hash partition groups, you must also specify the
partition_by_second_hash_columnsandpartition_by_second_hash_bucketstable properties. The following is an example: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 )NoteThis example defines two hash partition groups. The first group distributes rows into two partitions based on the
col1column. The second group distributes rows into three partitions based on thecol2column. The table has a total of six partitions (2 × 3).
-
-
Range partition
A Kudu table can have at most one range partition, which you can define using the
partition_by_range_columnstable property. When you create the table, you can define the partition ranges using therange_partitionstable property. To manage range partitions on an existing table, use thekudu.system.add_range_partitionandkudu.system.drop_range_partitionstored procedures. The following is an example: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}]' )NoteThis example defines a table with two hash partition groups and one range partition on the
event_timecolumn. The range is split at the timestamp2018-01-01T00:00:00. -
Manage range partitions
The following examples show partition operations:
-
Add a range partition
CALL kudu.system.add_range_partition(<YOUR_SCHEMA_NAME>, <YOUR_TABLE_NAME>, <range_partition_as_json_string>) -
Drop a range partition
CALL kudu.system.drop_range_partition(<YOUR_SCHEMA_NAME>, <YOUR_TABLE_NAME>, <range_partition_as_json_string>)
Parameter
Description
<YOUR_SCHEMA_NAME>The schema where the table is located.
<YOUR_TABLE_NAME>The name of the table.
<range_partition_as_json_string>The upper and lower bounds of the range partition, specified as a JSON string. Use the format
'{"lower": <value>, "upper": <value>}'. If the partition has multiple columns, use the format'{"lower": [<value_col1>,...], "upper": [<value_col1>,...]}'. The value format depends on the column's data type. The following list maps data types to their required JSON string formats:-
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: A Base64-encoded string.
NoteA
nullvalue indicates an unbounded boundary.The following is an example:
CALL kudu.system.add_range_partition('myschema', 'events', '{"lower": "2018-01-01", "upper": "2018-06-01"}')NoteThis example adds a range partition to the
eventstable in themyschemaschema. The lower bound of the partition is2018-01-01, which corresponds to the timestamp2018-01-01T00:00:00.000. The upper bound is2018-06-01.Use the
SHOW CREATE TABLEstatement to view existing range partitions. This information appears in therange_partitionstable property. -
Add a column
Use the ALTER TABLE ... ADD COLUMN ... statement to add a column to an existing table. You can also specify column properties for the new column. For details about column properties, see Create a table.
ALTER TABLE mytable ADD COLUMN extraInfo varchar WITH (nullable = true, encoding = 'plain')