Impala是由Cloudera公司开发的新型查询系统,参照Dremel系统进行设计的。提供SQL语义,能查询存储在Hadoop的HDFS和HBase上的PB级大数据,在性能上比Hive高出3~30倍。
基于Hive的大数据实时分析查询引擎,其运行需要依赖于Hive元数据。Impala采用与商用并行关系数据库类似的分布式查询引擎,可以直接与HDFS和HBase进行交互查询。Impala和Hive采用相同的SQL语法、ODBC驱动程序和用户接口。Impalad核心进程,负责接收查询请求并向多个数据节点分发任务。statestored进程负责监控所有Impalad进程,并向集群中的节点报告各个Impalad进程的状态。catalogd进程负责广播通知元数据的最新信息
特性:
劣势:
相同点:
总结:
Impala和Hive、HDFS、HBase等工具是统一部署在一个Hadoop平台上的,主要由Impalad,State Store和CLI三部分组成:
说明:Impala中的元数据直接存储在Hive中。Impala采用与Hive相同的元数据、SQL语法、ODBC驱动程序和用户接口,从而使得在一个Hadoop平台上,可以统一部署Hive和Impala等分析工具,同时支持批处理和实时查询。
Hive查看所有内置函数:
show functions;-- hive仅显示函数的名称, 没有参数和返回值信息
desc function <function_name>;-- 该命令能显示函数的具体用途
Impala支持java/c++编写UDF,impala内置很多UDF,查看内置UDF方法:
use _impala_builtins;-- 自带数据库
show functions;-- 查看内置UDF,会显示完整的函数签名信息
cast(expr AS type)
:类型转换函数,如将number转成string或相反
typeof()
:该函数可以用来检查其他函数返回值类型,hive 没有对应的函数
version()
:返回 impalad 版本
pid()
:client连接到impalad 的 pid
user()
:返回连接连接 impalad 的 linux username
effective_user()
:一般情况下和和 user() 结果相同, 如果启用 delegation, effective_user() 返回代理 user id
uuid()
:返回一个唯一的 guid 值
impala 没有 sequence概念,但可使用concat(cast(unix_timestamp() as string), uuid())
, 前面加上时间戳, 可以保证大概的顺序.
coalesce(type v1, type v2, ...); -- 返回第一个非null的v,全部为null则返回null
decode(); -- 同Oracle的decode()函数
if(boolean condition, type ifTrue, type ifFalseOrNull); --如果第一参数为true,结果为第2个参数, 否则为第三个参数
ifnull(type a, type ifNull); -- 同nvl()
isnull(type a, type ifNull); --同nvl()
nullif(expr1,expr2); -- 两参数相等,返回null
nullifzero(numeric_expr); --参数为0,返回null
nullvalue(expression); --如果为null,返回true
nvl(type a, type ifNull); --如果第一个参数为null,结果为第二个参数,否则为第一个参数
nvl2(type a, type ifNull, type ifNotNull); --如果第一个参数为null,结果为第2个参数,否则为第3个参数
zeroifnull(numeric_expr);
nonnullvalue(expression);
isfalse(boolean);
isnotfalse(boolean);
isnottrue(boolean);
istrue(boolean);
describe formatted table
:可查询impala某个表的信息,比如 CreateTime 表示表的生成时间;
元数据是记录数据的数据。Impala的数据就是文件,而元数据是记录文件存在什么位置,多少个,大小,时间等。
invalidate metadata和refresh
refresh轻量级,适用于数据更新(不是Impala途径增加或者删除数据)的场景;
invalidate metadata,适用于表结构发生改变(非Impala途径创建或者修改表结构);
收集统计信息:compute stats db.table
查看表统计信息:show table stats db.table
查看字段统计信息:show column stats db.table
用途:
join query缺少统计信息时,可能会生成错误的执行计划,查询缓慢;
建表语句中的location指向实际数据的路径;
了解一个表的基本类别可以通过show create table
命令;
删除impala的一行数据:不是delete
创建表时可通过指定location来指定表文件的存放路径,如果不指定的话,默认是将数据存放在/user/hive/warehouse/库名
下。未被external修饰的表是内部表(managed table),被external修饰的是外部表(external table)
区别:
/user/hive/warehouse/目录
下(这个目录是可以在配置文件中修改的)。收集信息使用COMPUTE STATS
命令,查看信息使用show table/column stats
。
和HIVE的ANALYZE TABLE类似,这个命令主要也是为了优化查询。本来IMPALA是依靠HIVE的ANALYZE TABLE的,但是这个命令不是很好用同时不稳定,所以IMPALA自己实现个命令完成相同功能。
有两类,语法:
# 全量
COMPUTE STATS [db_name.]table_name
# 增量
COMPUTE INCREMENTAL STATS [db_name.]table_name [PARTITION (partition_spec)]
作用:
收集有关表中数据的容量和分布以及所有相关列和分区的信息。这些信息存储在metastore数据库中,Impala使用这些信息来帮助优化查询。
区别:
COMPUTE STATS适用于全量,操作更重量级,适合非分区表;
COMPUTE INCREMENTAL STATS适用于增量,操作轻量级,适合分区表;
> show table stats t2;
| #Rows | #Files | Size | Format |
±------±-------±---------±-------+
| -1 | 28 | 960.00KB | TEXT |
> show column stats t1;
| Column | Type | #Distinct Values | #Nulls | Max Size | Avg Size |
±-------±-------±-----------------±-------±---------±---------+
| id | INT | -1 | -1 | 4 | 4 |
| s | STRING | -1 | -1 | -1 | -1 |
join算法有两类:
broadcast,广播连接,Impala默认方式,大表一定要放在左边,因为impala在广播右侧表,所有右侧表会复制到需要右侧表进行联接的所有节点。右侧的表被认为比左侧的表小,并且它的内容被发送到查询涉及到的其他节点上。
在join后面加[shuffle],将broadcast join转换为shuffle join,
替代的技术称作分割连接(partitioned join,与分区表无关),更适用于近乎相同大小的大型表的连接,每一个表的部分内容被发送到对应的其他节点,然后这些行的子集可以并行处理。广播和分区连接的选择仍然依赖于连接中所有表的可用的、使用 COMPUTE STATS 语句的统计信息。
Impala join查询最简单的优化手段就是通过使用compute stats来收集join中每张表的统计信息,然后由Impala根据表的大小、列的唯一值数目等来自动优化查询。为了更加精确地获取每张表的统计信息,每次表的数据变更时(如执行insert、load data、add partition、或drop partition等)都要重新执行一遍compute stats
。
若join查询中表的统计信息不全或者Impala选择的join顺序不是最优时,可在select [distinct 、all]
后指定straight_join
来覆盖掉impala的join顺序:
select straight_join x
from medium join small join (select * from big where c1 < 10) as big
where medium.id = small.id and small.id = big.id;
select distinct straight_join x
from medium join small join (select * from big where c1 < 10) as big
where medium.id = small.id and small.id = big.id;
这样Impala就会使用查询语句中表的顺序来指导join的处理。
使用STRAIGHT_JOI技术时,须手动指定join查询中表的顺序而不是依赖于Impala优化器。Impala优化器使用特殊的手段来估算join中每个阶段的结果集大小,而对于手动指定顺序来说,可以根据如下方式开始,然后再手动调节来达到最优:
如表的大小如下:BIG、MEDIUM、SMALL和TINY,那顺序应该如此:BIG join TINY join SMALL join MEDIUM。
Impala查询优化器根据表的绝对或者相对大小来选择不同技术来执行join查询。
broadcast或者partition join的选择是根据compute stats采集到的可用统计指标来衡量的。对于指定查询语句,可以通过执行EXPLAIN就可以查看选用的是哪个join策略。
当join中表或者列的统计指标不可用时,Impala将无统计指标的表认为统计指标都为0,这些表都将作为右表处理。
通常对于大数据量来说,Parquet文件格式是最佳的
参考:如何在Impala中使用Parquet表
ILIKE:忽略大小写的 like 操作符
REGEXP:正则匹配操作符
RLIKE:同 REGEXP 操作符
IREGEXP:忽略大小写的正则匹配符
IS DISTINCT FROM:判断前后两个表达式是否不相等,和<>
操作符类似,但 null IS DISTINCT FROM null 返回 false
IS not DISTINCT FROM:判断前后两个表达式是否相等,和=操作符类似,唯一不同的是,处理 null 时候,null IS not DISTINCT FROM null 结果为 ture
set mem_limit=-1;
set DISABLE_UNSAFE_SPILLS=0/FALSE;
0/FALSE
时,内存运算濒临溢出时转为磁盘运算;1/TRUE
时,当内存溢出时直接报内存溢出Memory limit exceeded
错误java.sql.SQLException:memory limit exceeded
常见原因:在优化之前,可先拿到查询计划,类似mysql explain
查询计划。在执行后也可以查看详细的执行信息。
Impala提供三种方式得知查询计划
EXPLAIN语句概述了查询将执行的逻辑步骤,例如如何在节点间分配工作以及中间结果如何合并为最终结果, 这些你都可以在查询真正执行之前获得,你可以使用这些信息来检查查询是否会以某种非高效的方式执行。
explain select ds,count(*) from t_ed_xxxx_newuser_read_feature_n group by ds order by ds;
| Max Per-Host Resource Reservation: Memory=9.94MB |
| Per-Host Resource Estimates: Memory=27.00MB |
| |
| PLAN-ROOT SINK |
| | |
| 05:MERGING-EXCHANGE [UNPARTITIONED] |
| | order by: ds ASC |
| | |
| 02:SORT |
| | order by: ds ASC |
| | |
| 04:AGGREGATE [FINALIZE] |
| | output: count:merge(*) |
| | group by: ds |
| | |
| 03:EXCHANGE [HASH(ds)] |
| | |
| 01:AGGREGATE [STREAMING] |
| | output: sum_init_zero(default.t_ed_xxxx_newuser_read_feature_n.parquet-stats: num_rows) |
| | group by: ds |
| | |
| 00:SCAN HDFS [default.t_ed_xxxx_newuser_read_feature_n] |
| partitions=372/372 files=2562 size=15.15GB
自底向上读取EXPLAIN的输出:
00阶段:显示了底层的详细信息,如:扫描的表,表的分区数,文件数以及文件大小等信息,根据这些信息,你可以估算大概的耗时
01阶段:聚合操作SUM并行地在不同的节点上执行
03阶段:将01阶段的结果进行传输
04阶段:将SUM结果进行合并
02阶段:排序操作并行地在不同的节点中进行
05阶段:排序结果合并,并且输出
EXPLAIN也会在PROFILE结果的头部输出。
SUMMARY命令可以输出每一阶段的耗时,可以快速地了解查询的性能瓶颈,与PROFILE输出一样,它只能在查询之后才可用,并且显示实际的时间消耗。SUMMARY输出也会在PROFILE的头部输出的显示。
select ds,count(*) from t_ed_xxxx_newuser_read_feature_n group by ds order by ds;
summary;
+---------------------+--------+----------+----------+-------+------------+----------+---------------+--------------------------------------------+
| Operator | #Hosts | Avg Time | Max Time | #Rows | Est. #Rows | Peak Mem | Est. Peak Mem | Detail |
+---------------------+--------+----------+----------+-------+------------+----------+---------------+--------------------------------------------+
| 05:MERGING-EXCHANGE | 1 | 3.20s | 3.20s | 372 | 372 | 0 B | 0 B | UNPARTITIONED |
| 02:SORT | 51 | 517.22us | 2.54ms | 372 | 372 | 6.02 MB | 6.00 MB | |
| 04:AGGREGATE | 51 | 1.75ms | 7.85ms | 372 | 372 | 2.12 MB | 10.00 MB | FINALIZE |
| 03:EXCHANGE | 51 | 2.91s | 3.10s | 2.44K | 372 | 0 B | 0 B | HASH(ds) |
| 01:AGGREGATE | 51 | 135.29ms | 474.62ms | 2.44K | 372 | 2.03 MB | 10.00 MB | STREAMING |
| 00:SCAN HDFS | 51 | 1.08s | 2.58s | 2.56K | 96.53M | 1.05 MB | 1.00 MB | default.t_ed_xxxx_newuser_read_feature_n |
PROFILE和SUMMAY区别
profile:输出底层信息计划
summary:查看查询时间及占用内存
区别不重要,都可用。
除了查询计划,最佳实践:
insert ... values
会产生大量小文件,应该避免使用)insert ... select
语句将其转换为Parquet格式.insert ... select
语句创建的Parquet文件都是每个分区256M(在2.0之后改为1G),通过Impala写入的Parquet文件只有一个块,因而只能被一个机器当作一个单元进行处理。如果在你的Parquet表中只有一个或者几个分区,或者一个查询只能访问一个分区,那么你的性能会非常慢,因为没有足够的数据来利用Impala并发分布式查询的优势。compute stats
)-B, --output_delimiter
)具体地:
参考Excel连接Impala
RuntimeFilter 是Impala 2.5及更高版本中可用的优化特性 。当针对分区表进行查询,或join条件仅需要表中的一小部分数据时,Impala会在查询运行时确定适当的条件,并将该信息广播到所有正在读取数据的impalad节点,以便它们可以避免不必要的IO,并仅输出与之匹配的数据子集来避免不必要的网络传输。
Impala高性能探秘之Runtime Filter
kudu pk parquet—runtime filter实践
Impala - Runtime Filter的原理及实现