Impla On Kudu方式
表类别:
内部表
内部表由 Impala 管理,当您从 Impala 中删除它时,数据和表会真正被删除。当您使用 Impala 创建新表时,它通常是一个内部表。
外部表
外部表(由 创建CREATE EXTERNAL TABLE
)不由 Impala 管理,删除此类表不会从其源位置(此处为 Kudu)删除该表。相反,它只删除了 Impala 和 Kudu 之间的映射。这是 Kudu 提供的用于将现有表映射到 Impala 的语法中使用的模式。
表的复制因子
TBLPROPERTIES ('kudu.num_tablet_replicas' = 'n')指定值,其使用Impala创建的kudu表默认的复制因子是3个。
当指定了复制因子后,是无法通过Alter Table修改的,只能使用CREATE TABLE … AS SELECT重新创建表指定复制因子。
Impala数据库和Kudu数据库
使用Impala创建Kudu表的时候格式默认为 impala::database_name.table_name
SQL中的谓词优化
如果WHERE
您的查询子句包含与运算符 =
, <=
, '<', '>', >=
, BETWEEN
, or的比较IN
,Kudu 将直接评估条件并仅返回相关结果。这提供了最佳性能,因为 Kudu 只将相关结果返回给 Impala。对于谓词!=
、LIKE
或 Impala 支持的任何其他谓词类型,Kudu 不会直接评估谓词,而是将所有结果返回给 Impala 并依赖 Impala 评估剩余的谓词并相应地过滤结果。这可能会导致性能差异,具体取决于评估WHERE
子句之前和之后结果集的增量。
分区方式
注意:分区的字段都必须在主键中存在
HASH分区
CREATE TABLE cust_behavior ( id BIGINT, sku STRING, salary STRING, edu_level INT, usergender STRING, `group` STRING, city STRING, postcode STRING, last_purchase_price FLOAT, last_purchase_date BIGINT, category STRING, rating INT, fulfilled_date BIGINT, PRIMARY KEY (id, sku) ) PARTITION BY HASH PARTITIONS 16 STORED AS KUDU;
Range分区
CREATE TABLE customers ( state STRING, name STRING, purchase_count int, PRIMARY KEY (state, name) ) PARTITION BY RANGE (state) ( PARTITION VALUE = 'al', PARTITION VALUE = 'ak', PARTITION VALUE = 'ar', -- ... etc ... PARTITION VALUE = 'wv', PARTITION VALUE = 'wy' ) STORED AS KUDU;
Hash和Range分区混用的方式
CREATE TABLE cust_behavior ( id BIGINT, sku STRING, salary STRING, edu_level INT, usergender STRING, `group` STRING, city STRING, postcode STRING, last_purchase_price FLOAT, last_purchase_date BIGINT, category STRING, rating INT, fulfilled_date BIGINT, PRIMARY KEY (id, sku) ) PARTITION BY HASH (id) PARTITIONS 4, RANGE (sku) ( PARTITION VALUES < 'g', PARTITION 'g' <= VALUES < 'o', PARTITION 'o' <= VALUES < 'u', PARTITION 'u' <= VALUES ) STORED AS KUDU; -- 上表先根据 id Hash分区成4个tablet,然后再将这4个tablet中的每一个分区为4个tablet,则总共将会有16个tablet CREATE TABLE cust_behavior ( id BIGINT, sku STRING, salary STRING, edu_level INT, usergender STRING, `group` STRING, city STRING, postcode STRING, last_purchase_price FLOAT, last_purchase_date BIGINT, category STRING, rating INT, fulfilled_date BIGINT, PRIMARY KEY (id, sku) ) PARTITION BY HASH (id) PARTITIONS 4, HASH (sku) PARTITIONS 4 STORED AS KUDU;
数据写入不存在的分区中
CREATE TABLE sales_by_year ( year INT, sale_id INT, amount INT, PRIMARY KEY (year, sale_id) ) PARTITION BY RANGE (year) ( PARTITION VALUE = 2012, PARTITION VALUE = 2013, PARTITION VALUE = 2014, PARTITION VALUE = 2015, PARTITION VALUE = 2016 ) STORED AS KUDU; -- 当year = 2017年的数据写入的时候,该数据将会被丢弃,并报错。 -- 新增分区的语句为: ALTER TABLE sales_by_year ADD RANGE PARTITION VALUE = 2017; -- 删除分区的语句为: ALTER TABLE sales_by_year DROP RANGE PARTITION VALUE = 2012;
分区的经验法则
-
对于大型表,例如事实表,目标是与集群中的核心数量一样多的Tablet。
-
对于维度表等小型表,请确保每个 tablet 的大小至少为 1 GB。
通常,在当前实现中,请注意Tablet的数量限制了读取的并行性。将Tablet的数量显着增加超过核心数量可能会导致收益递减。
注意Kudu的一些限制:
1. 在 Impala 中用作外部表时,必须为名称包含大写或非 ascii 字符的 Kudu 表分配一个备用名称。 2. 列名包含大写或非 ascii 字符的 Kudu 表不能用作 Impala 中的外部表。可以在 Kudu 中重命名列以解决此问题。 3. 创建 Kudu 表时,该CREATE TABLE语句必须按主键顺序在其他列之前包含主键列。 4. Impala 无法创建具有嵌套类型列的 Kudu 表。 5. Impala 无法更新主键列中的值。 6. !=和LIKE谓词不会推送到 Kudu,而是由 Impala 扫描节点评估。相对于其他类型的谓词,这可能会降低性能。 7. 通过 Impala 进行的更新、插入和删除是非事务性的。如果查询中途失败,其部分影响将不会回滚。 8. 单个查询的最大并行度受限于表中的 tablet 数量。为获得良好的分析性能,大型表的目标是每台主机 10 个或更多tablet。 列数 默认情况下,Kudu 不允许创建超过 300 列的表。我们建议使用较少列的架构设计以获得最佳性能。 细胞大小 在编码或压缩之前,单个单元格的大小不得大于 64KB。在 Kudu 完成内部复合密钥编码后,组成复合密钥的单元总共限制为 16KB。插入不符合这些限制的行将导致错误返回给客户端。 行的大小 尽管单个单元格可能高达 64KB,并且 Kudu 最多支持 300 列,但建议单行不要超过几百 KB。 有效标识符 表名和列名等标识符必须是有效的 UTF-8 序列,并且不超过 256 个字节。 不可变主键 Kudu 不允许您更新一行的主键列。 不可更改的主键 Kudu 不允许您在创建表后更改主键列。 不可更改的分区 Kudu 不允许您在创建后更改表的分区方式,添加或删除范围分区除外。 不可更改的列类型 Kudu 不允许更改列的类型。 分区拆分 创建表后不能拆分或合并分区。 不回收已删除的行磁盘空间 被删除的行占用的磁盘空间只能通过压缩回收,并且只有当删除的年龄超过“Tablet历史最大年龄”(由 --tablet_history_max_age_sec标志控制)时。此外,Kudu 目前仅调度压缩以提高读/写性能;Tablet 永远不会纯粹为了回收磁盘空间而压缩。因此,当预计会丢弃大量行时,应使用范围分区。使用范围分区,可以删除单个分区以丢弃数据并回收磁盘空间。
Kudu的设计架构
https://github.com/apache/kudu/blob/master/docs/design-docs/tablet.md