kudu实践


本文使用的版本Impala 3.2.0Kudu 1.10.0

MySQL单表迁移至Kudu

1、将MySQL中的表导出为csv文件格式

我这里使用的是Navicat自带的导出功能

  • 导出格式 CSV 文件( *.csv )

在这里插入图片描述

  • 随便从库中选择一个表

在这里插入图片描述

  • 选择要导出的字段,一般都是全选

在这里插入图片描述

  • 文本标识符号选 ”无“,不然导出的数据全部带标识符。

在这里插入图片描述

  • 导出结束

在这里插入图片描述

2、将CSV文件上传至HDFS中

因为impala不支持导入本地文件,所以要先上传到HDFS上,再加载数据

[root@master01 ~]# hdfs dfs -mkdir -p /upload/data/
[root@master01 ~]# hdfs dfs -chmod -R 777 /upload/data/
[root@master01 ~]# hdfs dfs -put /root/test_table/jk_answer_ext_4.csv /upload/data/
[root@master01 ~]# hdfs dfs -ls /upload/data/

3、impala临时表

建库

[worker03.cdh:21000] default> create database jkDB;
Query: create database jkDB
+----------------------------+
| summary                    |
+----------------------------+
| Database has been created. |
+----------------------------+
Fetched 1 row(s) in 0.16s

建表

[worker03.cdh:21000] default> use jkDB;
Query: use jkDB
[worker03.cdh:21000] jkDB> CREATE TABLE jk_answer_ext_4_temp (id BIGINT COMMENT '回答ID',content STRING COMMENT '回答内容',suggest STRING COMMENT '意见建议' ) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';
Query: CREATE TABLE jk_answer_ext_4_temp (id BIGINT COMMENT '回答ID',content STRING COMMENT '回答内容',suggest STRING COMMENT '意见建议' ) ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
+-------------------------+
| summary                 |
+-------------------------+
| Table has been created. |
+-------------------------+
Fetched 1 row(s) in 0.07s

导入数据

[worker03.cdh:21000] jkDB> load data inpath '/upload/data/jk_answer_ext_4.csv' into table jk_answer_ext_4_temp;
Query: load data inpath '/upload/data/jk_answer_ext_4.csv' into table jk_answer_ext_4_temp
+----------------------------------------------------------+
| summary                                                  |
+----------------------------------------------------------+
| Loaded 1 file(s). Total files in destination location: 1 |
+----------------------------------------------------------+
Fetched 1 row(s) in 4.13s

4、kudu表

创建

[worker03.cdh:21000] jkDB> CREATE TABLE jk_answer_ext_4 (id BIGINT COMMENT '回答ID',content STRING COMMENT '回答内容',suggest STRING COMMENT '意见建议',PRIMARY KEY(id)) PARTITION BY HASH PARTITIONS 16 STORED AS KUDU;
Query: CREATE TABLE jk_answer_ext_4 (id BIGINT COMMENT '回答ID',content STRING COMMENT '回答内容',suggest STRING COMMENT '意见建议',PRIMARY KEY(id)) PARTITION BY HASH PARTITIONS 16 STORED AS KUDU
+-------------------------+
| summary                 |
+-------------------------+
| Table has been created. |
+-------------------------+
Fetched 1 row(s) in 0.56s

从impala临时表jk_answer_ext_4_temp 导入kudu表jk_answer_ext_4 ,这一步如果表太大的话,适当加大impala内存。

[worker03.cdh:21000] jkDB> insert into jk_answer_ext_4 select * from jk_answer_ext_4_temp;

查看kudu库中的表

[root@master01 test_table]# kudu table list 10.0.0.180
impala::jkDB.jk_answer_ext_4

Kudu基本操作

对 kudu 的操作使用 impala 实现,这也是官网推荐的一种方法

库操作

  • kudu 没有数据库的概念,所以创建的数据库只是 impala 的一个 namespace,之后创建的表、视图、函数只是存在相同的 namespace 中。
  • 创建的数据库会以目录的形式 /user/hive/warehouse/xxx.db 存放在 HDFS 文件系统中。表(内部表)、分区和数据文件都位于此目录下。
  • 在 impala 中创建的表全名为:impala::database_name.table_name
  • impala 有一个初始的默认库 default ,如不指定其他库,则默认在 default 中操作。
  • impala 包含另一个预定义的数据库,_impala_builtins,用于存放内置函数的库。
  • 当数据库通过USE语句选择该数据库时,不能删除该数据库。
  • 在删除数据库之前,首先先删除其中的所有表。或者使用 CASCADE 语句,drop database temp cascade;

创建数据库

CREATE (DATABASE|SCHEMA) 
  [IF NOT EXISTS] 
  database_name 
  [COMMENT 'database_comment'] 
  [LOCATION hdfs_path];
[worker01.cdh:21000] default> CREATE DATABASE IF NOT EXISTS dev_spa COMMENT '研发库' LOCATION '/user/impala/';
Query: CREATE DATABASE IF NOT EXISTS dev_spa COMMENT '研发库' LOCATION '/user/impala/'
+----------------------------+
| summary                    |
+----------------------------+
| Database has been created. |
+----------------------------+
WARNINGS: Impala does not have READ_WRITE access to path 'hdfs://master01.cdh:8020/user'

Fetched 1 row(s) in 0.16s

查看所有数据库

[worker01.cdh:21000] jkDB> show databases;
Query: show databases
+------------------+----------------------------------------------+
| name             | comment                                      |
+------------------+----------------------------------------------+
| _impala_builtins | System database for Impala builtin functions |
| default          | Default Hive database                        |
| impala_kudu      |                                              |
| jkdb             |                                              |
| poc_test         |                                              |
| test_db          |                                              |
+------------------+----------------------------------------------+
Fetched 6 row(s) in 0.00s

使用数据库

[worker01.cdh:21000] jkDB> use test_db;
Query: use test_db

查看当前使用的数据库

[worker01.cdh:21000] test_db> SELECT current_database();
Query: SELECT current_database()
Query submitted at: 2021-08-24 11:09:55 (Coordinator: http://worker01.cdh:25000)
Query progress can be monitored at: http://worker01.cdh:25000/query_plan?query_id=5a498b482a1675cb:d24e1acb00000000
+--------------------+
| current_database() |
+--------------------+
| test_db            |
+--------------------+
Fetched 1 row(s) in 0.11s

删除数据库

在使用当前的数据库时,无法删除当前的数据库,需要离开当前库,然后再删除该库;

[worker01.cdh:21000] test_db> drop database test_db;
Query: drop database test_db
ERROR: AnalysisException: Cannot drop current default database: test_db

[worker01.cdh:21000] test_db> use default;
Query: use default

[worker01.cdh:21000] default> drop database test_db;
Query: drop database test_db
+----------------------------+
| summary                    |
+----------------------------+
| Database has been dropped. |
+----------------------------+
Fetched 1 row(s) in 0.03s

表操作

创建表

创建一个新的表,并指定其特性。

  • 该表是内部的还是外部的。

  • 列和关联的数据类型。

primitive_type:
 | TINYINT
 | SMALLINT
 | INT
 | BIGINT
 | BOOLEAN
 | FLOAT
 | DOUBLE
 | DECIMAL
 | STRING
 | CHAR
 | VARCHAR
 | TIMESTAMP
complex_type:
 | struct_type
 | array_type
 | map_type
  • 用于物理分区数据的列。
  • 数据文件的文件格式。
file_format:
 | PARQUET
 | TEXTFILE
 | AVRO
 | SEQUENCEFILE
 | RCFILE
  • 数据文件所在的HDFS目录。

语法

CREATE [EXTERNAL] TABLE [IF NOT EXISTS] [db_name.]table_name
 (col_name data_type
 [COMMENT 'col_comment']
 [, ...]
 )
 [PARTITIONED BY (col_name data_type [COMMENT 'col_comment'], ...)]
 [SORT BY ([column [, column ...]])]
 [COMMENT 'table_comment']
 [ROW FORMAT row_format]
 [WITH SERDEPROPERTIES ('key1'='value1', 'key2'='value2', ...)]
 [STORED AS file_format]
 [LOCATION 'hdfs_path']
 [CACHED IN 'pool_name' [WITH REPLICATION = integer] | UNCACHED]
 [TBLPROPERTIES ('key1'='value1', 'key2'='value2', ...)]

CTAS建表语法

CREATE [EXTERNAL] TABLE [IF NOT EXISTS] db_name.]table_name
 [PARTITIONED BY (col_name[, ...])]
 [SORT BY ([column [, column ...]])]
 [COMMENT 'table_comment']
 [ROW FORMAT row_format]
 [WITH SERDEPROPERTIES ('key1'='value1', 'key2'='value2', ...)]
 [STORED AS ctas_file_format]
 [LOCATION 'hdfs_path']
 [CACHED IN 'pool_name' [WITH REPLICATION = integer] | UNCACHED]
 [TBLPROPERTIES ('key1'='value1', 'key2'='value2', ...)]
AS
 select_statement

查看库中所有表

[worker01.cdh:21000] default> show tables in jkdb;
Query: show tables in jkdb
+-------------------------+
| name                    |
+-------------------------+
| jk_answer_ext_4         |
| jk_answer_ext_4_temp    |
| jk_chunyu_askcaiji_temp |
+-------------------------+
Fetched 3 row(s) in 0.00s
# 或
[worker01.cdh:21000] default> use jkdb;
Query: use jkdb
[worker01.cdh:21000] jkdb> show tables;
Query: show tables
+-------------------------+
| name                    |
+-------------------------+
| jk_answer_ext_4         |
| jk_answer_ext_4_temp    |
| jk_chunyu_askcaiji_temp |
+-------------------------+
Fetched 3 row(s) in 0.00s

查看表结构

[worker01.cdh:21000] default> describe t1_table;
Query: describe t1_table
+------+--------+---------+-------------+----------+---------------+---------------+---------------------+------------+
| name | type   | comment | primary_key | nullable | default_value | encoding      | compression         | block_size |
+------+--------+---------+-------------+----------+---------------+---------------+---------------------+------------+
| id   | bigint |         | true        | false    |               | AUTO_ENCODING | DEFAULT_COMPRESSION | 0          |
| name | string |         | false       | true     |               | AUTO_ENCODING | DEFAULT_COMPRESSION | 0          |
+------+--------+---------+-------------+----------+---------------+---------------+---------------------+------------+
Fetched 2 row(s) in 2.67s

查看建表语句

[worker01.cdh:21000] default> show create table t1_table;
Query: show create table t1_table
+------------------------------------------------------------------------------+
| result                                                                       |
+------------------------------------------------------------------------------+
| CREATE TABLE default.t1_table (                                              |
|   id BIGINT NOT NULL ENCODING AUTO_ENCODING COMPRESSION DEFAULT_COMPRESSION, |
|   name STRING NULL ENCODING AUTO_ENCODING COMPRESSION DEFAULT_COMPRESSION,   |
|   PRIMARY KEY (id)                                                           |
| )                                                                            |
| PARTITION BY HASH (id) PARTITIONS 16                                         |
| STORED AS KUDU                                                               |
| TBLPROPERTIES ('kudu.master_addresses'='master01.cdh')                       |
+------------------------------------------------------------------------------+
Fetched 1 row(s) in 0.00s

插入数据

# 插入一行
INSERT INTO t1_table VALUES (99, "sarah");
# 插入多行
INSERT INTO t1_table VALUES (1,"john"), (2,"jane"), (3,"jim");
# 批量插入
-- 1.多条单一的INSERT语句,这种方法的优点是易于理解和实施。这种方法可能效率不高,因为与Kudu的插入性能相比,Impala具有较高的查询启动成本。这将导致较高的延迟和较差的吞吐量。
INSERT INTO t1_table VALUES (1,"john");
INSERT INTO t1_table VALUES (2,"jane");
INSERT INTO t1_table VALUES (3,"jim");
-- 2.一条INSERT包含多个VALUES,如果您包含1024个以上的VALUES语句,则Impala batch_size在将请求发送到Kudu之前将它们分成1024个组。此方法可能比多个INSERT语句要好一些,但是要提前设置impala配置,set batch_size=10000;
SET batch_size=10000;
INSERT INTO t1_table VALUES (1,"john"), (2,"jane"), (3,"jim"),...,(9999,'timi');
-- 3.使用SELECT FROM从impala中的表导入
INSERT INTO t1_table SELECT * FROM other_table;

更新数据

[worker01.cdh:21000] default> update t1_table set name = 'wangyu' where id = 2;
Query: update t1_table set name = 'wangyu' where id = 2
Query submitted at: 2021-08-24 15:30:21 (Coordinator: http://worker01.cdh:25000)
Query progress can be monitored at: http://worker01.cdh:25000/query_plan?query_id=74499c9848c45c63:23c7221400000000
Modified 1 row(s), 0 row error(s) in 0.12s
UPSERT INTO tank_test_2 VALUES (1, "tank", "2020-01-07","tank");  //upsert语法,第一次见

删除数据

[worker01.cdh:21000] default> delete from t1_table where id = 99;
Query: delete from t1_table where id = 99
Query submitted at: 2021-08-24 15:24:23 (Coordinator: http://worker01.cdh:25000)
Query progress can be monitored at: http://worker01.cdh:25000/query_plan?query_id=5f435e63f215f901:69f14aaf00000000
Modified 1 row(s), 0 row error(s) in 0.12s

添加列

[worker01.cdh:21000] default> alter table t1_table add columns(phone int,time_stamp string);
Query: alter table t1_table add columns(phone int,time_stamp string)
+----------------------------+
| summary                    |
+----------------------------+
| Column(s) have been added. |
+----------------------------+
Fetched 1 row(s) in 0.13s

删除列

[worker01.cdh:21000] default> alter table t1_table drop column time_stamp;
Query: alter table t1_table drop column time_stamp
+--------------------------+
| summary                  |
+--------------------------+
| Column has been dropped. |
+--------------------------+
Fetched 1 row(s) in 0.10s

修改表名

[worker01.cdh:21000] default> alter table t1_table rename to r1_table;
Query: alter table t1_table rename to r1_table
+--------------------------+
| summary                  |
+--------------------------+
| Renaming was successful. |
+--------------------------+
Fetched 1 row(s) in 0.09s

删除表

[worker01.cdh:21000] default> drop table t1_table;
Query: drop table t1_table
+-------------------------+
| summary                 |
+-------------------------+
| Table has been dropped. |
+-------------------------+
Fetched 1 row(s) in 0.05s

创建视图

CREATE VIEW IF NOT EXISTS kudu_view1 AS
SELECT
e.name,d.house
from kudu_table e
INNER JOIN kudu_table3 d
ON e.id= d.id;

3、kudu命令行

版本1.10:https://kudu.apache.org/releases/1.10.0/docs/command_line_tools_reference.html#table

  • 列出kudu中的表
kudu table list <master_addresses> [-tables=<tables>] [-list_tablets]
  • 删除指定的表
kudu table delete <master_addresses> <table_name> [-nomodify_external_catalogs]
  • 修改指定表的表名
kudu table rename_table <master_addresses> <table_name> <new_table_name>
  • 修改指定表的列名
kudu table rename_column <master_addresses> <table_name> <column_name> <new_column_name>
  • 复制一个表数据到另一个kudu库中
kudu table copy <master_addresses> <table_name> <dest_master_addresses> [-nocreate_table] [-dst_table=<table>] [-num_threads=<threads>] [-predicates=<predicates>] [-tablets=<tablets>] [-write_type=<type>]
  • 扫描表中的每一行
kudu table scan <master_addresses> <table_name> [-columns=<columns>] [-nofill_cache] [-num_threads=<threads>] [-predicates=<predicates>] [-tablets=<tablets>]
  • 描述指定的表
kudu table describe <master_addresses> <table_name> [-show_attributes]
  • 定位每行属于哪个tablet
kudu table locate_row <master_addresses> <table_name> <primary_key> [-check_row_existence]

注意点

官网链接:
https://docs.cloudera.com/documentation/enterprise/6/6.3/topics/kudu_limitations.html
https://kudu.apache.org/releases/1.10.0/docs/schema_design.html#_the_perfect_schema

设计模式的局限性

主键 Primary Key

  • 在创建表之后,不能更改主键。必须删除并重新创建表以选择新的主键。
  • 设置主键的列必须为表的首列。
  • 不能使用UPDATE功能修改主键。若要修改一行的主键,必须删除该行并使用修改的键重新插入该行。这样的修改是非原子的。
  • DOUBLEFLOATBOOL类型的列不允许设置为主键。此外,主键列必须是NOT NULL
  • 不支持自动生成主键。
  • 在Kudu完成内部复合键编码之后,组成复合主键的单元格总数被限制为16KB。

单元 Cells

在编码或压缩之前,单个单元不能大于64KB。
在Kudu完成内部复合键编码之后,组成复合键的单元格总数被限制为16KB。
插入不符合这些限制的行将导致错误返回给客户端。

列 Columns

  • 默认情况下,Kudu表最多可以有300列。我们推荐使用较少列的设计模式以获得最佳性能。
  • 不支持CHARVARCHARDATE和其他复杂类型,如:ARRAYMAPSTRUCT
  • 现有列的类型和可空性不能通过更改表来更改。
  • 删除列不会立即回收空间。必须首先运行压缩。
  • DECIMAL列的精度和比例不能通过更改表来更改。

表 Tables

  • 表必须有奇数个副本,最多7个。
  • 不能更改复制因子(在创建表时设置)。
  • 没有办法手动运行压缩,但是删除表将立即回收空间。

其他使用限制

  • 不支持二级索引。
  • 不支持多行事务。
  • 不支持关系特性,如外键。
  • 诸如列和表名称之类的标识符被限制为有效的UTF-8字符串。此外,最大长度为256个字符。

分区的限制

  • 每个表的主键必须提前手动进行分区,目前还不支持自动分区。除了添加或删除范围分区,Kudu不允许在创建表之后更改分区方式。
  • 现有表中的数据目前无法自动重新分区。有一个解决方案就是使用新的分区创建一个新表,并将旧表的数据插入。
  • 如果有大部分Tablets的副本丢失,需要人工干预才能修复。

拓展建议和限制

Kudu可以在以下规模的环境和负载中无缝运行:

  • 推荐Master最大数量为3。

  • 推荐Tablet Server最大数量为100。

  • 推荐的最大存储数据量,复制后和压缩后,每个Tablet Server服务器8TiB。

  • 每个Tablet Server服务器推荐的tablets数量为1000片(复制后),每个Tablet Server服务器允许的最大tablets数量为2000片。

  • 在创建表时,每个表服务器的每个表的最大表数为 60。

  • 在创建表时,每个tablet 服务器的每个table 的最大tablet 数为60,复制后(假设默认复制因子为3)。

  • 建议每片平板电脑的最大数据量为 50 GiB。超出此范围可能会导致性能降低、压缩问题和平板电脑启动时间缓慢等问题。

  • 平板电脑的推荐目标大小低于 10 GiB。

  • 主服务器数量:3

  • 300多台平板服务器

  • 每个平板电脑服务器 10+ TiB 的存储数据,复制后和压缩后

  • 每个平板电脑服务器超过 4000 个平板电脑,复制后

  • 每个平板电脑 50 GiB 的存储数据。超出此范围可能会导致性能降低、压缩问题和平板电脑启动时间变慢等问题。

服务器管理限制

  • 生产部署应该为平板电脑服务器配置至少 4 GiB 的内存,在接近数据和平板电脑规模限制时最好配置超过 16 GiB。
  • 预写日志 (WAL) 只能存储在一个磁盘上。
  • 无法删除数据目录。您必须重新格式化数据目录才能删除它们。
  • 平板服务器无法正常退役。
  • 平板服务器无法更改其地址或端口。
  • Kudu 对拥有最新的 NTP 有严格的要求。Kudu 主服务器和平板服务器在不同步时会崩溃。
  • Kudu 版本仅使用 NTP 进行了测试。Chrony 等其他时间同步提供程序可能无法工作。

集群管理限制

  • 不支持滚动重启。
  • Kudu 集群内建议的最大点对点延迟为 20 毫秒。
  • Kudu 集群内推荐的最小点对点带宽为 10 Gbps。
  • 如果您打算使用位置感知功能将平板电脑服务器放置在不同的位置,建议您测量服务器之间的带宽和延迟,以确保它们符合上述准则。
  • 第一次启动集群时,必须同时启动所有主节点。

复制和备份限制

  • Kudu 目前不包含任何用于备份和恢复的内置功能。鼓励用户根据需要使用 Spark 或 Impala 等工具导出或导入表。

Impala 集成限制

  • 创建 Kudu 表时, 创建表 语句必须按主键顺序在其他列之前包含主键列。

  • Impala 无法更新主键列中的值。

  • Impala 无法创建 Kudu 表 VARCHAR 或嵌套类型的列。

  • 当 Kudu 表用作 Impala 中的外部表时,必须为名称包含大写或非 ASCII 字符的 Kudu 表分配一个备用名称。

  • 列名包含大写或非 ASCII 字符的 Kudu 表不能用作 Impala 中的外部表。可以在 Kudu 中重命名列以解决此问题。

  • != 和 喜欢谓词不会推送到 Kudu,而是由 Impala 扫描节点评估。相对于其他类型的谓词,这可能会降低性能。

  • 使用 Impala 的更新、插入和删除是非事务性的。如果查询中途失败,其部分效果将不会回滚。

  • 单个查询的最大并行度受限于表中的平板电脑数量。为了获得良好的分析性能,每个主机的目标是 10 个或更多平板电脑或使用大表。

  • 创建 Kudu 表不支持 Impala 关键字 PARTITIONED、 LOCATION、 ROWFORMAT

Kudu 复制因子

默认情况下,通过 Impala 创建的 Kudu 表使用的平板复制因子为 3。要更改 Kudu 表的复制因子,请在CREATE TABLE 语句语句中使用 TBLPROPERTIES 指定复制因子,如下所示,其中n是您想要的复制因子用:

TBLPROPERTIES ('kudu.num_tablet_replicas' = 'n')

Kudu 表的副本数必须是奇数。

Kudu 表的 Impala DDL 增强

Kudu 表的主键列

Kudu 表首次向 Impala 引入了主键的概念。主键由一列或多列组成,这些列的值在查询过程中被组合并用作查找键。这些列所代表的元组必须是唯一的,并且不能包含任何空值,并且一旦插入就永远无法更新。对于 Kudu 表,所有分区键列必须来自主键列。

主键具有物理和逻辑两个方面:

  • 在物理方面,它用于将数据值映射到特定的tablets以进行快速检索。由于主键值形成的元组是唯一的,主键列通常具有高度选择性。
  • 在逻辑方面,唯一性约束允许您避免表中的重复数据。例如,如果一个插入操作中途失败,表中可能只有一些新行。您可以重新运行相同的插入,并且只会添加缺少的行。或者,如果表中的数据陈旧,您可以运行UPSERT 使数据保持最新状态的语句,而不可能创建现有行的重复副本。

CREATE TABLE 指定 Kudu 列属性

以下部分提供了您可以在列定义中使用的一些特定于 Kudu 的关键字的更多详细信息。

  PRIMARY KEY
| [NOT] NULL
| ENCODING codec
| COMPRESSION algorithm
| DEFAULT constant_expression
| BLOCK_SIZE number

PRIMARY KEY属性

Kudu 表的主键是唯一标识每一行的一列或一组列。主键值还用作表中值的自然排序顺序。每行的主键值基于列值的组合。

因为所有的主键列都必须有非空值,所以在 PRIMARY KEY 子句默认地添加了 NOT NULL 属性到该列。

主键列必须是创建表语句中指定的第一个主键列。

对于单列主键,您可以包含一个 PRIMARY KEY 与列定义内联的属性。对于多列主键,您包括一个 PRIMARY KEY (c1, c2, …) 子句作为列列表末尾的单独条目。

CREATE TABLE pk_inline
(
  col1 BIGINT PRIMARY KEY,
  col2 STRING,
  col3 BOOLEAN
) PARTITION BY HASH(col1) PARTITIONS 2 STORED AS KUDU;

CREATE TABLE pk_at_end
(
  col1 BIGINT,
  col2 STRING,
  col3 BOOLEAN,
  PRIMARY KEY (col1)
) PARTITION BY HASH(col1) PARTITIONS 2 STORED AS KUDU;
CREATE TABLE pk_multiple_columns
(
  col1 BIGINT,
  col2 STRING,
  col3 BOOLEAN,
  PRIMARY KEY (col1, col2)
) PARTITION BY HASH(col2) PARTITIONS 2 STORED AS KUDU;

主键的概念仅适用于 Kudu 表。每个 Kudu 表都需要一个主键。主键由一列或多列组成。您必须首先在列列表中指定任何主键列。

NULL | NOT NULL 属性

对于 Kudu 表,您可以指定哪些列可以包含或不包含空值。此约束为 Kudu 表提供了额外级别的一致性强制。

CREATE TABLE required_columns
(
  id BIGINT PRIMARY KEY,
  latitude DOUBLE NOT NULL,
  longitude DOUBLE NOT NULL,
  place_name STRING,
  altitude DOUBLE,
  population BIGINT
) PARTITION BY HASH(id) PARTITIONS 2 STORED AS KUDU;

DEFAULT 属性

您可以为 Kudu 表中的列指定默认值。默认值可以是任何常量表达式,例如,文字值、算术和字符串运算的组合。它不能包含对列或非确定性函数调用的引用。

CREATE TABLE default_vals
(
  id BIGINT PRIMARY KEY,
  name STRING NOT NULL DEFAULT 'unknown',
  address STRING DEFAULT upper('no fixed address'),
  age INT DEFAULT -1,
  earthling BOOLEAN DEFAULT TRUE,
  planet_of_origin STRING DEFAULT 'Earth',
  optional_col STRING DEFAULT NULL
) PARTITION BY HASH(id) PARTITIONS 2 STORED AS KUDU;

ENCODING 属性

Kudu 表中的每一列都可以选择使用编码,这是一种降低磁盘大小的低开销压缩形式,然后需要额外的 CPU 周期来在查询期间重建原始值。通常,高度可压缩的数据受益于从磁盘读回数据的 I/O 减少。
Impala 识别的编码关键字是:
AUTO_ENCODING:使用基于列类型的默认编码,数字类型列使用bitshuffle,字符串类型列使用字典。
PLAIN_ENCODING:保留原始二进制格式的值。
RLE:通过包含计数来压缩重复值(按主键顺序排序时)。
DICT_ENCODING:当不同字符串值的数量较少时,将原始字符串替换为数字 ID。
BIT_SHUFFLE:重新排列值的位以有效地压缩基于主键顺序相同或仅略有不同的值序列。生成的编码数据也用 LZ4 压缩。
PREFIX_ENCODING:压缩字符串值中的公共前缀;主要在 Kudu 内部使用。

以下示例显示了表示编码类型的 Impala 关键字。(Impala 关键字与 Kudu 中使用的符号名称匹配。)有关不同类型编码的使用指南,请参阅Kudu 文档。DESCRIBE 输出显示了在创建表后如何报告编码,以及省略编码(在这种情况下,对于 ID 列)与指定相同 DEFAULT_ENCODING.

CREATE TABLE various_encodings
(
  id BIGINT PRIMARY KEY,
  c1 BIGINT ENCODING PLAIN_ENCODING,
  c2 BIGINT ENCODING AUTO_ENCODING,
  c3 TINYINT ENCODING BIT_SHUFFLE,
  c4 DOUBLE ENCODING BIT_SHUFFLE,
  c5 BOOLEAN ENCODING RLE,
  c6 STRING ENCODING DICT_ENCODING,
  c7 STRING ENCODING PREFIX_ENCODING
) PARTITION BY HASH(id) PARTITIONS 2 STORED AS KUDU;

-- Some columns are omitted from the output for readability.
describe various_encodings;
+------+---------+-------------+----------+-----------------+
| name | type    | primary_key | nullable | encoding        |
+------+---------+-------------+----------+-----------------+
| id   | bigint  | true        | false    | AUTO_ENCODING   |
| c1   | bigint  | false       | true     | PLAIN_ENCODING  |
| c2   | bigint  | false       | true     | AUTO_ENCODING   |
| c3   | tinyint | false       | true     | BIT_SHUFFLE     |
| c4   | double  | false       | true     | BIT_SHUFFLE     |
| c5   | boolean | false       | true     | RLE             |
| c6   | string  | false       | true     | DICT_ENCODING   |
| c7   | string  | false       | true     | PREFIX_ENCODING |
+------+---------+-------------+----------+-----------------+

COMPRESSION 属性

您可以指定用于 Kudu 表中每一列的压缩算法。LZ4, SNAPPY, ZLIB

CREATE TABLE blog_posts
(
  user_id STRING ENCODING DICT_ENCODING,
  post_id BIGINT ENCODING BIT_SHUFFLE,
  subject STRING ENCODING PLAIN_ENCODING,
  body STRING COMPRESSION LZ4,
  spanish_translation STRING COMPRESSION SNAPPY,
  esperanto_translation STRING COMPRESSION ZLIB,
  PRIMARY KEY (user_id, post_id)
) PARTITION BY HASH(user_id, post_id) PARTITIONS 2 STORED AS KUDU;

BLOCK_SIZE 属性

虽然 Kudu 在内部不使用 HDFS 文件,因此不受 HDFS 块大小的影响,但它确实有一个称为块大小的 I/O 底层单位。BLOCK_SIZE 属性允许您为任何列设置块大小。

Kudu 表的分区

Kudu 表使用特殊机制在底层tablet servers服务器之间分配数据。尽管我们将此类表称为分区表,但它们与传统 Impala 分区表的区别在于使用了不同的 CREATE TABLE 语句。Kudu 表使用 PARTITION BY, HASH, RANGE, 和范围规范条款而不是 PARTITIONED BY HDFS 支持的表的子句,它只指定一个列名并为每个不同的值创建一个新分区。

Hash 分区

Hash 分区是 Kudu 表最简单的分区类型。对于哈希分区的表,

Range 分区

1、建库

  1. 数据库名字不支持 - 字符,会报错
[worker02.cdh:21000] default> create database temp-tenant;
Query: create database temp-tenant
ERROR: ParseException: Syntax error in line 1:
create database temp-tenant
                    ^
Encountered: -
Expected: COMMENT, LOCATION

CAUSED BY: Exception: Syntax error

2、建表

以下为impala 3.2.0支持的数据类型
在这里插入图片描述

  1. CHAR数据类型要带上长度,不然会报错
ERROR: ParseException: Syntax error in line 6:
  `state` char COMMENT '状态',
               ^
Encountered: COMMENT
Expected: (

CAUSED BY: Exception: Syntax error

正确语法

column_name CHAR(length)

由于kudu不支持char类型,该表要是作为临时表,最后导入kudu的话,最好将该字段设置为kudu也支持的类型,例如bigint

  1. AUTO_INCREMENT不支持,会报错
ERROR: ParseException: Syntax error in line 2:
  `id` bigint  AUTO_INCREMENT,
               ^
Encountered: IDENTIFIER
Expected: BLOCK_SIZE, COMMENT, COMPRESSION, DEFAULT, ENCODING, INTERMEDIATE, LOCATION, NOT, NULL, PRIMARY, COMMA
  1. DATETIME不支持,记得转成TIMESTAMP
ERROR: AnalysisException: Unsupported data type: DATETIME
  1. Kudu不支持Char数据类型

所以建表的时候尽量把char换成bigint

ERROR: AnalysisException: Cannot create table 'living_room': Type CHAR(1) is not supported in Kudu

猜你喜欢

转载自blog.csdn.net/qq_39680564/article/details/119873752