不生产博客,只是官网的搬运工
https://docs.cloudera.com/documentation/enterprise/5-16-x/topics/kudu_impala.html
impala与kudu集成,允许你使用impala sql来插入、查询和更新、删除kudu的数据,作为kudu api的替代方案,另外,也可以使用jdbc or odbc
impala数据库包含模型(不知道该咋翻译)
Impala Database Containment Model
每个impala表包含叫做库的namespace,默认的database是default,当需要的时候可以创建或删除额外的数据库,使用create database语句来创建库,use database,进入该库
create database db;
use db;
create table tab()
前缀impala::和数据库名被追加到kudu表前面,impala::db.tab
内部表和外部表
类似hive的内、外表,内部表由impala管理,删除表连kudu数据一起删除,外部表只会删除impala、kudu的映射,默认内部表,前缀是impala::db.tab
用impala查kudu表
查询已经存在表,通过api或者spark创的表,impala这看不到,需要创映射
CREATE EXTERNAL TABLE my_mapping_table
STORED AS KUDU
TBLPROPERTIES (
'kudu.table_name' = 'exist_kudu_table'
);
创建新的kudu表
用impala创Kudu需要指定schema和分区信息,impala首先创建Kudu表,然后创建映射
创建分区表
create table
CREATE TABLE my_first_table
(
id BIGINT,
name STRING,
PRIMARY KEY(id)
)
PARTITION BY HASH PARTITIONS 16
STORED AS KUDU;
默认副本数3,副本数必须奇数,需要指定的话添加:
TBLPROPERTIES ('kudu.num_tablet_replicas' = 'n')
create table ... as select ...
CREATE TABLE new_table
PRIMARY KEY (ts, name)
PARTITION BY HASH(name) PARTITIONS 8
STORED AS KUDU
AS SELECT ts, name, value FROM old_table;
可以select xxx as new_filed_name,作为新字段名
分区表
支持hash、range
range分区
CREATE TABLE customers (
state STRING,
name STRING,
....
PRIMARY KEY (state, name)
)
PARTITION BY RANGE (state)
(
PARTITION VALUE = 'al',
PARTITION VALUE = 'ak',
PARTITION VALUE = 'ar',
...
...
PARTITION VALUE = 'wv',
PARTITION VALUE = 'wy'
)
STORED AS KUDU;
hash分区
hash(a),hash(b) hash(a,b)都可以
但hash(a),hash(a,b)将报错
CREATE TABLE cust_behavior (
id BIGINT,
sku STRING,
.....
PRIMARY KEY (id, sku)
)
PARTITION BY HASH PARTITIONS 16 --默认以主键分区
STORED AS KUDU;
高级分区
创建16个分区
hash+range
CREATE TABLE cust_behavior (
id BIGINT,
sku STRING,
.....
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;
多hash创16个分区
也可以hash(id,sku),但这样查sku的话,会scan 所有分区,不会限制在4个里面
CREATE TABLE cust_behavior (
id BIGINT,
sku STRING,
....
PRIMARY KEY (id, sku)
)
PARTITION BY HASH (id) PARTITIONS 4,
HASH (sku) PARTITIONS 4
STORED AS KUDU;
STORED AS KUDU;
非覆盖-range分区
下面例子可以存储12年到16年5年的数据
CREATE TABLE sales_by_year (
year INT, sale_id INT, amount INT,
PRIMARY KEY (sale_id, year)
)
PARTITION BY RANGE (year) (
PARTITION VALUE = 2012,
PARTITION VALUE = 2013,
PARTITION VALUE = 2014,
PARTITION VALUE = 2015,
PARTITION VALUE = 2016
)
STORED AS KUDU;
当有17年数据的时候,可以加range分区
ALTER TABLE sales_by_year ADD RANGE PARTITION VALUE = 2017;
当不需要12年数据的时候,drop即可
ALTER TABLE sales_by_year DROP RANGE PARTITION VALUE = 2012;
分区规则:
对于大表,分区数与集群cores数一致
对于小表,每个分区至少1G(有什么依据吗?之前测试,6个节点,6个分区(忽略副本),每个分区大概2G多数据,然后分12个,效率提升很明显,分成18个后,几乎没啥提升)
sql谓词评估对于性能优化
如果where条件包含=、<=、<、>、>=、between或者in,kudu将按照条件直接将结果给impala,提升性能,对于!=、like等等,kudu会将所有数据给Impala,impala自己做过滤
insert数据
INSERT INTO my_first_table VALUES (99, "sarah");
INSERT INTO my_first_table VALUES (1, "john"), (2, "jane"), (3, "jim");
批量插入,3种方式,各有利弊
1.多个insert语句,效率比较差,与kudu插入相比,impala有较高的启动成本
2.多个values子句,impala会默认按1020分组,然后将数据交给kudu,可以设置批次大小来调节效率
set batch_size=10000;
修改表的properties
ALTER TABLE my_table RENAME TO my_new_table;--只是修改了impala映射
ALTER TABLE my_internal_table
SET TBLPROPERTIES('kudu.table_name' = 'new_name');--仅限内部表,修改kudu底层表名
ALTER TABLE my_external_table_
SET TBLPROPERTIES('kudu.table_name' = 'some_other_kudu_table');--修改外部表到别的kudu表
ALTER TABLE my_table
SET TBLPROPERTIES('kudu.master_addresses' = 'ip:7051,...');--修改master地址
ALTER TABLE my_table SET TBLPROPERTIES('EXTERNAL' = 'TRUE');--内部表修改为外部