2.impala 实操

教程 阿布都的都 ⋅ 于 2023-01-06 20:32:54 ⋅ 1128 阅读

1 impala操作环境

1.1 impala-shell

# 创建 impala 用户和认证凭证
kadmin.local
    addprinc -pw impala impala@HAINIU.COM
    xst -norandkey -k /data/impala.keytab impala
    exit

# 认证impala
kinit -kt /data/impala.keytab impala
klist

# 默认连接impala方式
impala-shell

# 企业用法:连接impala时指定impalad
#-i:指定impalad节点(可以是任意节点)
#-k:采用kerberos认证方式登录
impala-shell -i worker-1 -k

# 在impala里查看数据库列表, 发现元数据缺失,这是因为impala没有把hive的元数据同步过来,需要同步hive元数据到impala
show databases;

# 同步元数据
invalidate metadata

注意:

​ 实际生产环境下,-i参数至关重要,如果有多个并行任务,可以通过-i参数将任务均衡分发到不同的impalad节点上。

1.2 hue操作impala

1.2.1 使用admin admin 登陆,进入管理界面

file

1.2.2 添加组

file

输入组名和设置权限

file

1.2.3 添加用户

file

file

file

file

1.2.4 使用impala用户登录

输入 impala impala 登录

file

-- 执行测试
select * from test;
create table test2(id string);

在安全环境下需要kerberos安全认证与sentry授权,认证与授权参照kerberos+sentry实操

2 impala-shell实操

impala-shell 实操与 hue 实操命令一致。

impala 基本语句与 hive 基本一致。

2.1 创建测试表并加载数据

-- 创建临时表
create table if not exists xinniu.impala_t1(
    col1 int,
    col2 boolean,
    col3 timestamp,
    col4 string
)
comment '临时加载表'
row format delimited fields terminated by '\t';

-- 造测试数据
vim tmp1
1   true    2021-08-20 12:20:00 ssd
3   false   2021-08-20 12:30:00 ssm
2   true    2021-08-20 11:30:00 ssc
4   true    2021-08-20 11:20:00 ssa
6   true    2021-08-20 12:20:00 skd
5   false   2021-08-20 12:30:00 smm
8   true    2021-08-20 13:30:00 smc
9   true    2021-08-20 13:20:00 sma
7   true    2021-08-20 14:20:00 smd
10  false   2021-08-20 14:30:00 skm
12  true    2021-08-20 15:30:00 skc
11  true    2021-08-20 15:20:00 ska

-- 用hdfs认证后,上传到hdfs目录
hadoop fs -put tmp1 /user/impala

-- 加载数据
load data inpath '/user/impala/tmp1' overwrite into table xinniu.impala_t1;

-- 创建parquet正式表(基于源表表结构创建)
create table if not exists xinniu.impala_parquet1
stored as parquet 
tblproperties ("parquet.compress"="SNAPPY")
as 
select * from xinniu.impala_t1
where 1=0;

-- 自己根据字段类型创建
CREATE TABLE xinniu.impala_parquet1 (                                        
  col1 INT,                                                                  
  col2 BOOLEAN,                                                              
  col3 TIMESTAMP,                                                            
  col4 STRING                                                                
)                                                                            
STORED AS PARQUET                                                            
TBLPROPERTIES ('parquet.compress'='SNAPPY') ;

-- 临时表加载数据到正式表
insert overwrite table xinniu.impala_parquet1
select * from xinniu.impala_t1;

file

2.2 数据导出

impala不支持 insert overwrite 的方式导出数据,需要使用-o outputpath的方式导出。

#参数解释:
# -i:指定impalad节点
# -k:使用kerberos认证方式
# -q:查询语句(也可以使用-f sql文件的方式) 
# -B --output_delimiter:指定输出文件分隔符 
# -o:输出文件

# 输出文件字段按照\t分隔
impala-shell -i worker-1 -k -q "select * from xinniu.impala_parquet1 limit 5;" -B --output_delimiter="\t" -o /data/output.txt 

# 默认输出
impala-shell -i worker-1 -k -q "select * from xinniu.impala_parquet1 limit 5;"  -o /data/output2.txt 

# 输出文件字段按照|分隔
impala-shell -i worker-1 -k -q "select * from xinniu.impala_parquet1 limit 5;"  -B --output_delimiter="|" -o /data/output1.txt 

# 执行SQL文件导出
impala-shell -i worker-1 -k -f test.sql  -o /data/output4.txt 
# 其中 test.sql 文件中的内容:
select * from xinniu.impala_parquet1 limit 5;

默认输出格式:

file

2.3 查询语句

查询语句与hive基本一致

-- 在排序语句中使用offset 即从offset位置开始输出
select * from xinniu.impala_parquet1 order by col1 desc limit 5;

select * from xinniu.impala_parquet1 order by col1 desc limit 5 offset 2;

file

2.4 union与union all

-- union去重 union all不去重

-- union 
select * from xinniu.impala_parquet1
union 
select * from xinniu.impala_parquet1;

-- union all
select * from xinniu.impala_parquet1
union all 
select * from xinniu.impala_parquet1;

-- hive union是有bug的
-- impala的union没有这个bug
select * from xinniu.impala_parquet1 t1 inner join xinniu.impala_parquet1 t2 on  t1.col1=t2.col1
union 
select * from xinniu.impala_parquet1 t1 inner join xinniu.impala_parquet1 t2 on  t1.col1=t2.col1;

2.5 日期时间类型

-- hive的orc格式支持date类型
-- 【hive创建的表】
create table if not exists xinniu.hive_orc(
    pk string,
    col2 timestamp
)
comment 'test date type'
stored as orc
tblproperties ("orc.compress"="SNAPPY");

--  hive的orc格式支持date类型,impala什么格式都不支持date类型,统一使用timestamp
--  【impala创建的】
create table if not exists xinniu.impala_parquet2(
    pk string,
    col2 timestamp
)
comment 'test date type'
stored as parquet
tblproperties ("parquet.compress"="SNAPPY");

-- 时间转换

-- 获取当前时间戳
select current_timestamp();
-- hive:2021-07-12 01:34:44.436
-- impala:2021-07-12 01:35:06.752796000

-- 获取1970年1月1日到当前时间的秒数,bigint类型
select unix_timestamp(current_timestamp());
-- typeof() 查看当前函数结果类型
select typeof(unix_timestamp(current_timestamp()));

-- 格式化成字符串
-- 默认格式: yyyy-MM-dd HH:mm:ss
select from_unixtime(unix_timestamp(current_timestamp()));
-- 指定格式
select from_unixtime(unix_timestamp(current_timestamp()), 'yyyyMMdd');

-- 给日期格式字符串或日期时间格式字符串,都可以格式化成指定格式的字符串
select from_unixtime(unix_timestamp('2021-08-20'), "yyyy-MM-dd HH:mm:ss");
select from_unixtime(unix_timestamp('2021-08-20 11:22:33'), "yyyy-MM-dd HHmmss");

select from_timestamp(cast(unix_timestamp(current_timestamp()) as timestamp),"yyyy-MM-dd");
select from_timestamp(cast(unix_timestamp('2021-08-20') as timestamp),"yyyy-MM-dd");
select from_timestamp(cast(unix_timestamp('2021-08-20 11:22:33') as timestamp),"yyyy-MM-dd");

2.6 转码函数

-- 加密
select base64encode('hainiu');
-- 解密
select base64decode('aGFpbml1');

#对数据脱敏的时候
身份证号、手机号、姓名、地址、账号

2.7 拼接字符串

-- hive执行
select concat('hello','hainiu');  -- hellohainiu
select concat_ws('_','hello','hainiu'); -- hello_hainiu
select concat('hello','hainiu',null); -- null
select concat_ws('_','hello','hainiu',null); -- hello_hainiu

-- 在impala中concat_ws(),有null出现则结果就为null
-- impala执行
select concat('hello','hainiu');  -- hellohaniu
select concat_ws('_','hello','hainiu'); -- hello_hainiu
select concat('hello','hainiu',null); -- null
select concat_ws('_','hello','hainiu',null); -- null

-- 获取第一个非空的值, 这个和hive用法一样,可作为赋默认值
select coalesce(null, null, 1,2);

2.8 字符串查找

-- 用于匹配子串在字符串中的位置(以1起点), 如果找不到返回0
select instr('/good_detail.action?id=001','/good_detail.action');
select instr('/good_search.action?id=001','/good_detail.action');

2.9 元数据同步

​ 由于Impala的架构设计,每一个impalad(coordinator角色)都会缓存一份自己的元数据信息。在impala中执行ddl语句之后,都需要通过catalog服务来广播到集群中的每一个节点。如果刚执行完ddl操作,立即到其他impalad 节点上查询,此时可能无法查到最新的修改。(多个impalad 才能测试出来)

有三种方式可以解决:

2.9.1 开启sync_ddl参数

在ddl语句前开启sync_ddl参数,在ddl语句结束后关闭,当前session有效,优先使用。

-- 影响最小,在一些create insert命令前打开自动同步功能
set SYNC_DDL=true;

create table xinniu.synctable(id string);

-- 在create insert 命令执行后关闭自动同步功能
set SYNC_DDL=false;

2.9.2 使用refresh db.tablename 表级增量刷新(推荐)

​ REFRESH是用于刷新某个表或者某个分区的数据信息,它会重用之前的表元数据,仅仅执行文件刷新操作,它能够检测到表中分区的增加和减少,主要用于表中元数据未修改,数据的修改,例如INSERT INTO、LOAD DATA、ALTER TABLE ADD PARTITION、ALTER TABLE DROP PARTITION等,如果直接修改表的HDFS文件(增加、删除或者重命名)也需要指定REFRESH刷新数据信息。

​ 影响其次并且指定表,如果没有打开sync_dll开关的情况下,优先使用这种方式去刷新元数据。

-- 语法格式:
-- 增量刷新全表
refresh table_name;  
-- 仅仅刷新指定分区
refresh [table_name] [PARTITION (key_col1=val1 [, key_col2=val2...])]];

refresh xinniu.synctable;

2.9.3 使用invalidate metadata 全量刷新

​ INVALIDATE METADATA是用于刷新全库或者某个表的元数据,包括表的元数据和表内的文件数据,它会首先清除表的缓存,然后从metastore中重新加载全部数据并缓存,该操作代价比较重,主要用于在hive中修改了表的元数据,需要同步到impalad,例如create table/drop table/alter table add columns等。

​ 注意:使用invalidate metadata 全量刷新,使所有impalad上缓存的元数据无效,尽量少用或者不用,一般生产上不允许使用,即使非要用也是invalidate metadata tablename的方式使用。

-- 影响范围是表
invalidate metadata xinniu.synctable;

-- 影响范围最大,即使已经有元数据的表,也会跟着一起刷新。
invalidate metadata

使用原则:

​ 1)如果只是涉及到表的数据改变,使用refresh [table]

​ 2)如果只是涉及到表的某一个分区数据改变,使用refresh [table] partition [partition]

​ 3)如果涉及到表的schema改变,使用invalidate metadata [table]

​ 4)禁止使用invalidate metadata什么都不加

2.10 解决中文注释乱码问题

修改hive的元数据表

修改编码后,之前创建的不能生效,只有以后创建的才会生效。

-- 修改元数据表编码
-- 修改数据编码为latin1
alter database metastore default character set latin1;
-- 修改表、列、分区、分区键、索引编码
use metastore;
alter table COLUMNS_V2 modify column COMMENT varchar(256) character set utf8;
alter table TABLE_PARAMS modify column PARAM_VALUE varchar(4000) character set utf8;
alter table PARTITION_PARAMS  modify column PARAM_VALUE varchar(4000) character set utf8;
alter table PARTITION_KEYS  modify column PKEY_COMMENT varchar(4000) character set utf8;
alter table  INDEX_PARAMS  modify column PARAM_VALUE  varchar(4000) character set utf8;

3 impala性能相关

​ impala关联操作左大右小,如果没有按照左大右小的规则写,impala会使用compute stats来收集join中每张表的统计信息,然后由Impala根据表的大小、列的唯一值数目等来自动优化查询。为了更加精确地获取每张表的统计信息,每次表的数据变更时(如执行insert、load data、add partition、或drop partition等)都要重新执行一遍compute stats。

-- 刷新全表统计信息
compute stats db.tablename;

-- 执行完dml语句时针对分区刷新表统计信息,此种方式只刷新了batch_date这个新增分区的信息到表统计信息中,相比compute stats效率要快
compute incremental stats db.tablename partition (pt in (${batch_date},''));

​ 在执行大批量任务的时候通常会有非常多任务脚本,在任务提交的时候应该轮询发送到不同的imapad节点上进行,而不应该在同一个impalad节点上执行,会导致单一impalad节点的oom,也严重影响并发性能,在执行的过程中通过-i指定impalad的节点。

impala-shell -k -i worker-1(impalad节点) -q "select ……" 或者 -f sql文件

4 impala执行计划解读

判断是否有表或者列统计信息

# straight_join : 当加了这个,就按照编写的SQL顺序进行join, 不用impala的优化器的优化方案。

# 直接按照当前顺序执行(本身就是左大右小)
explain 
select straight_join t1.*  
from 
(
  SELECT col1,col2 from xinniu.impala_t1
) t1
join
(
  select col1,col2 from xinniu.impala_t1 limit 5
) t2
on 
t1.col1=t2.col1;

# 按照impala的优化器优化方案执行(本身SQL是左小右大,优化器优化后变成左大右小)
explain select  *  
from 
(
  select col1,col2 from xinniu.impala_t1 limit 5
) t1
join
(
  SELECT col1,col2 from xinniu.impala_t1
) t2
on 
t1.col1=t2.col1;

# 直接按照当前顺序执行(本身SQL是左小右大)
explain select straight_join *  
from 
(
  select col1,col2 from xinniu.impala_t1 limit 5
) t1
join
(
  SELECT col1,col2 from xinniu.impala_t1
) t2
on 
t1.col1=t2.col1;

查看执行计划:

file

执行统计:

compute stats xinniu.impala_t1;

再次查看执行计划,发现警告信息已经没了:

file

在hue上可以查看执行计划树,并且可以直观的看到每个环节所用的时间。

file

file

版权声明:原创作品,允许转载,转载时务必以超链接的形式表明出处和作者信息。否则将追究法律责任。来自海汼部落-阿布都的都,http://hainiubl.com/topics/76073
成为第一个点赞的人吧 :bowtie:
回复数量: 0
    暂无评论~~
    • 请注意单词拼写,以及中英文排版,参考此页
    • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`, 更多语法请见这里 Markdown 语法
    • 支持表情,可用Emoji的自动补全, 在输入的时候只需要 ":" 就可以自动提示了 :metal: :point_right: 表情列表 :star: :sparkles:
    • 上传图片, 支持拖拽和剪切板黏贴上传, 格式限制 - jpg, png, gif,教程
    • 发布框支持本地存储功能,会在内容变更时保存,「提交」按钮点击时清空
    Ctrl+Enter