2019-08-08 17:40:17 星期四
概要描述
本案例详细介绍hyperdrive的SQL Bulkload操作流程,以及注意事项;
同时简单介绍了hyperdrive与hyperbase的SQL Bulkload操作的区别;
详细说明
Bulkload是一种快速向Hyperbase导入大量数据的方法;
SQL BulkLoad的适用场景为:
- 初次原始数据导入
- 增量数据导入
0、操作前准备工作
原始数据需要加载到 inceptor 表中,比如 BL_FOR_HYPERDRIVE_EXT 表
- 创建2个临时函数用以进行 split key 的编码转换
CREATE TEMPORARY FUNCTION HYPERDRIVE_PT_ENCODE AS "io.transwarp.hyperdrive.udf.UDFEncodePrimitiveType"; CREATE TEMPORARY FUNCTION HYPERDRIVE_ST_ENCODE AS "io.transwarp.hyperdrive.udf.UDFEncodeStructType";
1、采样生成SplitKey
在导入数据之前,用户需要对数据进行采样,根据采样结果可以生成splitkey,作为预分region的依据;
采样表即用来保存采样的结果,采样表列中必须包含用来生成rowkey的源表字段;
例如,使用源表中的 SS_SOLD_DATE_SK 字段会用来生成目标表的rowkey:
CREATE TABLE SAMPLETABLE
(SS_SOLD_DATE_SK INT)
STORED AS ORC;
1.1、存放采样结果
- 根据原始数据表收集采样结果
INSERT INTO TABLE SAMPLETABLE SELECT SAMPLE(8484 ,SS_SOLD_DATE_SK) FROM BL_FOR_HYPERDRIVE_EXT;
- 说明:
- Inceptor提供了sample函数用来生成splitkey;
- sample函数接受至少2个参数,第1个参数是采样率,采样率=数据条数/97/预分region数
- 样例数据有5760749条,预分7个region,因此采样率=5760749/97/7,即采样率为8484;
- 后面的参数为采样表中的列名;
- 用户需要根据自身业务场景和实际数据量,确定导入后目标表的rowkey,region数量;
此处与传统 hyperbase 表的 sql bulkload 不同,除了创建一张存放采样结果的表以外,还需要额外创建一张存放 split key 的表,如下:
2、创建splitkey表,并通过采样获取splitkey
-
创建一张存放 split key 的表,此表必须是 hbase 表类型
DROP TABLE IF EXISTS tmp_splitkeys; CREATE TABLE TMP_SPLITKEYS (KEY BINARY , VALUE BIGINT) STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler' TBLPROPERTIES ('hbase.table.name' = 'tmp_splitkeys');
生成splitkey并插入到splitkey表,后续建立映射表时需要指定splitkey表;
由于 hyperdrive 表中对 split key 的编码进行了调整,我们在生成 split key 的时需要用刚才创建的临时函数替代 concat() 函数;
使用该函数时,需要在每个要用到的字段后面设置字段长度,string 类型按需设置,其他类型设置为-1;
另外,拼接的字段必须是你将用在建表时作为rowkey的字段或其一部分,同时二者顺序必须一致且位于rowkey的最前端;INSERT INTO TABLE TMP_SPLITKEYS SELECT MID,1 FROM (SELECT MAX(C) AS MID FROM (SELECT HYPERDRIVE_ST_ENCODE(SS_SOLD_DATE_SK,-1) C , NTILE(7) OVER ( ORDER BY HYPERDRIVE_ST_ENCODE(SS_SOLD_DATE_SK,-1)) NT FROM SAMPLETABLE) GROUP BY NT) ORDER BY MID LIMIT 6;
- ntile函数的参数即为预分region的数量;
- limit的数量是预分region数量减一;
3、使用 Inceptor 建立 hyperbase 表的映射表
此时我们如果查询 splitkey 表,会发现 splitkey 的显示是乱码,这里其实已经是转换成二进制编码后的结果;
建立 hyperdrive 映射表;建表时语法略有不同,需要指定 split key 表和 region 数。
DROP TABLE BL_HYPERDRIVE_MAP_INCEPTOR;
CREATE TABLE BL_HYPERDRIVE_MAP_INCEPTOR
(KEY STRUCT 尖括号SS_SOLD_DATE_SK:INT, UUID:BIGINT尖括号
, SS_SOLD_DATE_SK INT
, SS_SOLD_TIME_SK INT
, SS_ITEM_SK INT
, SS_CUSTOMER_SK INT
, SS_CDEMO_SK INT
, SS_HDEMO_SK INT
, SS_ADDR_SK INT
, SS_STORE_SK INT)
STORED AS HYPERDRIVE
TBLPROPERTIES(
'hbase.table.splitkey.decode'='false',
'hbase.table.splitkey.tablename'='tmp_splitkeys',
'hbase.table.region.count'='7',
'COMPRESSION'='SNAPPY');
-- 另外,如果字段中有 struct 类型且含有 string 类型,则必须指定其长度,且需要在SERDEPROPERTIES 中要指定字段长度:'hyperdrive.structstring.length.struct_name.struct_field'='string_length',建表语句如下:
CREATE TABLE BL_HYPERDRIVE_MAP_INCEPTOR
(KEY STRUCT 尖括号SS_SOLD_DATE_SK:string LENGTH 18, UUID:bigint尖括号
, SS_SOLD_DATE_SK INT
, SS_SOLD_TIME_SK INT
, SS_ITEM_SK INT
, SS_CUSTOMER_SK INT
, SS_CDEMO_SK INT
, SS_HDEMO_SK INT
, SS_ADDR_SK INT
, SS_STORE_SK INT)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '|' COLLECTION ITEMS TERMINATED BY '\001' MAP KEYS TERMINATED BY '\003' LINES TERMINATED BY '\N'
STORED AS HYPERDRIVE
TBLPROPERTIES(
'hbase.table.splitkey.decode'='false',
'hbase.table.splitkey.tablename'='tmp_splitkeys',
'hbase.table.region.count'='7',
'COMPRESSION'='SNAPPY',
'hyperdrive.structstring.length.key.ss_sold_date_sk'='18');
5、使用SQL Bulkload导入数据
使用bulkload的方式从源表中将数据导入目标表
-- 个别版本没有 UUIQ 这个函数,此次只是举例,可以使用其他字段拼接为 struct 类型比如这样
-- NAMED_STRUCT('SS_SOLD_DATE_SK',SS_SOLD_DATE_SK,'UUID',SS_STORE_SK) NS_KEY
INSERT INTO TABLE BL_HYPERDRIVE_MAP_INCEPTOR
SELECT /*+USE_BULKLOAD*/
NAMED_STRUCT('SS_SOLD_DATE_SK',SS_SOLD_DATE_SK,'UUID',UNIQ()) NS_KEY
,SS_SOLD_DATE_SK INT
,SS_SOLD_TIME_SK INT
,SS_ITEM_SK INT
,SS_CUSTOMER_SK INT
,SS_CDEMO_SK INT
,SS_HDEMO_SK INT
,SS_ADDR_SK INT
,SS_STORE_SK INT
FROM BL_FOR_HYPERDRIVE_EXT ORDER BY NS_KEY;