使用Kudu連接器可以查詢、插入和刪除儲存在Kudu裡的資料。
背景資訊
本文為您介紹Kudu連接器相關的內容和操作,具體如下:
前提條件
已建立Trino叢集和Hadoop叢集,且Hadoop叢集選擇了Kudu服務,詳情請參見建立叢集。
使用限制
Kudu版本需要為1.10及以上。
Trino叢集和Hadoop叢集網路互連。
Kudu表名稱和列名稱僅支援小寫字母。
修改Kudu連接器配置
修改Kudu連接器配置,詳情請參見配置連接器。
進入EMR控制台的Trino服務的配置頁面,在服務配置地區,單擊kudu.properties頁簽。您可以看到以下參數,參數值請根據您實際情況修改。
參數 | 描述 |
kudu.client.master-addresses | Kudu主地址清單,多個地址時使用逗號(,)分隔。 支援以下格式:example.com、example.com:7051、192.0.2.1、192.0.2.1:7051、[2001:db8::1]、[2001:db8::1]:7051和2001:db8::1。 預設值為localhost。 說明 為了確保能夠對Kudu表進行寫入和查詢操作,請將預設的localhost更改為Kudu master節點的IP地址或主機名稱,例如:master-1-1。 |
kudu.schema-emulation.enabled | 是否開啟Schema類比功能。 取值如下:
重要 您可以在kudu.properties頁簽,單擊新增配置項添加該配置項,添加配置項詳情請參見添加配置項。 |
kudu.schema-emulation.prefix | Schema類比功能的首碼。 重要 當 標準首碼為 |
kudu.client.default-admin-operation-timeout | 管理操作(例如,Create Table、Delete Table等)的預設逾時。 預設值為30s。 |
kudu.client.default-operation-timeout | 使用者操作的預設逾時。 預設值為30s。 |
kudu.client.default-socket-read-timeout | 等待來自Socket的資料時使用的預設逾時。 預設值為10s。 |
kudu.client.disable-statistics | 是否啟用Kudu用戶端的統計資訊收集功能。取值如下:
|
資料查詢
Apache Kudu不支援Schema,但是通過配置Kudu Connector可以支援Schema功能。
不開啟Schema類比功能(預設行為)
Schema類比預設是關閉的,此時kudu的表都在default
的Schema下。
例如,您可以通過執行SELECT * FROM kudu.default.orders
來查詢表orders
,如果Catalog和 Schema分別指定為kudu
和default
,則查詢語句可以簡化為SELECT * FROM orders
。
Kudu的表名稱可以包含任一字元,因此需要用雙引號(")參考資料表名稱。例如,查詢表special.table!
,執行語句為SELECT * FROM kudu.default."special.table!"
。
樣本如下:
在
default
的Schema下建立表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 );
說明建立表時必須指定必要的表資訊,例如,主鍵、列的編碼格式或壓縮格式、Hash分區或Range分區等。
查看錶資訊。
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;
開啟Schema類比功能
如果在連接器的設定檔etc/catalog/kudu.properties裡設定了開啟Schema類比功能,則表會根據命名規範被映射到對應的Schema裡。
如果設定了
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不能直接支援Schema ,Presto會建立一個特殊表
$schemas
用來管理Schema。如果設定了
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不能直接支援Schema ,所以Presto會建立一個特殊表
presto::$schemas
用來管理Schema。
資料類型映射
下表為您介紹Presto資料類型和Kudu資料類型的對應情況。
Presto資料類型 | Kudu資料類型 | 備忘 |
BOOLEAN | BOOL | 無 |
TINYINT | INT8 | |
SMALLINT | INT16 | |
INTEGER | INT32 | |
BIGINT | INT64 | |
REAL | FLOAT | |
DOUBLE | DOUBLE | |
VARCHAR | STRING | 從Presto表建立Kudu表執行 |
VARBINARY | BINARY | |
TIMESTAMP | UNIXTIME_MICROS | kudu列的µs精度降低到ms精度。 |
DECIMAL | DECIMAL | 僅支援Kudu server的1.7.0及後續版本。 |
DATE | 無 | 不支援 從Presto表建立Kudu表執行 |
CHAR | 無 | 不支援 |
TIME | ||
JSON | ||
TIME WITH TIMEZONE | ||
TIMESTAMP WITH TIME ZONE | ||
INTERVAL YEAR TO MO NTH | ||
INTERVAL DAY TO SEC OND | ||
ARRAY | ||
MAP | ||
IPADDRESS |
支援的Presto SQL文法
不支援ALTER SCHEMA ... RENAME TO ...
。
SQL文法 | 備忘 |
| 無 |
| 無 |
| 無 |
| 無 |
| 僅在Schema啟用時可用。 |
| 僅在Schema啟用時可用。 |
| 建立表,詳情請參見建立表。 |
| 無 |
| 無 |
| 無 |
| 增加列,詳情請參見增加列。 |
| 僅對非主鍵可用。 |
| |
| 無 |
| 無 |
| 無 |
| 無 |
| 作用同 |
| 增加Range分區,詳情請參見Range分區。 |
| 刪除Range分區,詳情請參見Range分區。 |
建立表
建立表需要指定列、資料類型和分區資訊,也可以根據您實際的情況指定列編碼格式或壓縮格式。建立表示例如下。
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_id
和event_name
,通過user_id
列的HASH值劃分為5個分區,number_of_replicas
設定為3。
建立表時相關參數描述如下:
主鍵列必須放在前面,分區列必須選取自主鍵列。
number_of_replicas
:可選項,該值指定了tablet的副本數,且必須為奇數。如果沒有指定該配置,則使用Kudu Master 預設配置的副本數。Kudu支援Hash和Range兩種類型的分區。Hash分區根據Hash值分發資料行到多個桶中的一個桶。Range分區使用有序的Range分區鍵分發資料行,具體的Range分區必須被顯式建立。Kudu支援多級分區,一個表至少要有一個Hash或Range分區,但最多有一個Range分區,可以有多個Hash分區。
列屬性
除了指定列名稱和類型,還可以指定其他列屬性。
列屬性名稱 | 類型 | 描述 |
primary_key | BOOLEAN | 設定為true,則表示使用該列作為主鍵。 Kudu主鍵需要滿足唯一性限制式。當待插入資料行的主鍵已經存在,再插入與已有相同主索引值的行,則會導致更新已有的資料行,詳情請參見Primary Key Design。 |
nullable | BOOLEAN | 設定為true,則表示該列可以取null。 重要 主鍵列不可為null。 |
encoding | VARCHAR | 指定列編碼格式以節省儲存空間和提高查詢效能。 如果沒有指定該屬性,則Kudu根據列資料類型自動編碼。取值為auto、plain、bitshuffle、runlength、prefix、dictionary和group_varint,詳情資訊請參見Column Encoding。 |
compression | VARCHAR | 指定列壓縮格式。 如果沒有指定該屬性,Kudu會使用預設壓縮格式。取值為default、no、lz4、snappy和zlib,詳情資訊請參見Column compression。 |
樣本如下。
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 (...);
分區設計
一個表至少要有一個Hash或Range分區,但最多隻能有一個Range分區,可以有多個Hash分區。分區資訊如下:
Hash分區
定義一組分區
您可以使用表屬性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)的Hash分區,資料分布到4個分區。
定義兩組分區
如果需要定義兩個獨立的Hash分區組,可以再設定表屬性
partition_by_second_hash_columns
和partition_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 )
說明該樣本定義了兩組Hash分區,第一組Hash分區按照列col1對資料行分布到2個分區,第二組Hash分區按照列col2對資料行分布到3個分區,因此該表會有共計2*3=6個分區。
Range分區
kudu表最多可以有一個Range分區,可以使用表屬性
partition_by_range_columns
定義。在建立表的時候,可以使用表屬性range_partitions
定義分區範圍,表屬性kudu.system.add_range_partition
和kudu.system.drop_range_partition
可以對已有的表進行Range分區管理。樣本如下。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}]' )
說明該樣本定義了二組Hash分區和一個對
event_time
列進行Range分區的表,Range分區範圍由2018-01-01T00:00:00
進行分割。管理Range分區
對於已經存在的表,有2個預存程序可以增加和刪除Range分區。
分區操作樣本如下:
增加一個Range分區
CALL kudu.system.add_range_partition(<YOUR_SCHEMA_NAME>, <YOUR_TABLE_NAME>, <range_partition_as_json_string>)
刪除一個Range分區
CALL kudu.system.drop_range_partition(<YOUR_SCHEMA_NAME>, <YOUR_TABLE_NAME>, <range_partition_as_json_string>)
參數
描述
<YOUR_SCHEMA_NAME>
表所在的Schema。
<YOUR_TABLE_NAME>
表名稱。
<range_partition_as_json_string>
JSON格式表示的Range分區的上下邊界,格式為
'{"lower": <value>, "upper": <value>}'
,如果分區有多個列,則格式為'{"lower": [<value_col1>,...], "upper": [<value_col1>,...]}'
,上下邊界具體的取值形式由列資料類型決定。資料類型和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
增加了一個Range分區,該分區的下界是2018-01-01
,即精確值是2018-01-01T00:00:00.000
,分區的上界是2018-06-01
。您可以使用SQL語句
SHOW CREATE TABLE
查詢已經存在的Range分區,分區資訊通過表屬性range_partitions
展示。
增加列
您可以使用SQL語句ALTER TABLE ... ADD COLUMN ...
為已經存在的表增加資料列,還可以使用列屬性來增加資料列。列屬性的詳細資料,可以在建立表模組中查看。
ALTER TABLE mytable ADD COLUMN extraInfo varchar WITH (nullable = true, encoding = 'plain')