交互式查询工具impala
主要内容
第 1 部分 Impala概述(Impala是什么,优势,劣势,与Hive对⽐)
第 2 部分 Impala的安装(制作本地Yum源⽅式安装)
第 3 部分 Impala的架构原理(有哪些组件,组件的作⽤,查询流程,查询计划)
第 4 部分 Impala的使⽤(使⽤与Hive类似,编写sql⽅式;Impala的DDL,查询语法,导⼊数据)
第 5 部分 Impala的Java 开发(Java+C++,使⽤JDBC⽅式查询Impala)
第 6 部分 Impala的优化(负载均衡,Impala中的Join的优化)
Impala是Cloudera提供的⼀款开源的针对HDFS和HBASE中的PB级别数据进⾏交互式实时查询(Impala 速度快),Impala是参照⾕歌的新三篇论⽂当中的Dremel实现⽽来,其中旧三篇论⽂分别是 (BigTable,GFS,MapReduce)分别对应我们即将学的HBase和已经学过的HDFS以及MapReduce。
Impala最⼤卖点和最⼤特点就是快速,Impala中⽂翻译是⾼⻆羚⽺。
回顾前⾯⼤数据课程路线其实就是⼀个⼤数据从业者⾯对的⼤数据相关技术发展的过程
⽐如我们按照阶段划分⼀个⼤数据开发任务,会有:数据采集(⽇志⽂件,关系型数据库中),数据清洗 (数据格式整理,脏数据过滤等),数据预处理(为了后续分析所做的⼯作),数据分析:离线处理(T+1分 析),实时处理(数据到来即分析),数据可视化,机器学习,深度学习等
⾯对如此众多的阶段再加上⼤数据天⽣的⼤数据量问题没有任何⼀个框架可以完美cover以上每个阶 段。所以⼤数据领域有⾮常多框架,每个框架都有最适合⾃⼰的具体场景。⽐如:HDFS负责⼤数据量 存储,MapReduce(Hive)负责⼤数据量的分析计算。
之前学习的Hive以及MR适合离线批处理,但是对交互式查询的场景⽆能为⼒(要求快速响应),所以为了 解决查询速度的问题,Cloudera公司依据Google的Dremel开发了Impala,Impala抛弃了MapReduce 使⽤了类似于传统的MPP数据库技术,⼤⼤提⾼了查询的速度。
MPP是什么?
MPP (Massively Parallel Processing),就是⼤规模并⾏处理,在MPP集群中,每个节点资源都是独⽴ 享有也就是有独⽴的磁盘和内存,每个节点通过⽹络互相连接,彼此协同计算,作为整体提供数据服 务。
简单来说,MPP是将任务并⾏的分散到多个服务器和节点上,在每个节点上计算完成后,将各⾃部分的 结果汇总在⼀起得到最终的结果
对于MPP架构的软件来说聚合操作⽐如计算某张表的总条数,则先进⾏局部聚合(每个节点并⾏计算), 然后把局部汇总结果进⾏全局聚合(与Hadoop相似)。
Impala与Hive对⽐
Impala的技术优势
Impala没有采取MapReduce作为计算引擎,MR是⾮常好的分布式并⾏计算框架,但MR引擎更多的是⾯向批处理模式,⽽不是⾯向交互式的SQL执⾏。与 Hive相⽐:Impala把整个查询任务转为⼀棵执⾏计划树,⽽不是⼀连串的MR任务,在分发执⾏计划后,Impala使⽤拉取的⽅式获取上个阶段的执⾏结果,把结果数据、按执⾏树流式传递汇集,减少的了把中间结果写⼊磁盘的步骤,再从磁盘读取数据的开销。Impala使⽤服务的⽅式避免每次执⾏查询都需要启动的开销,即相⽐ Hive没了MR启动时间。
mr慢的原因: 1. shuffle阶段,比较多的IO ; 2. shuffle阶段默认对key分区排序
impala优势: 1. 避免数据落磁盘 2. 处理进程无需每次启动。3. impala默认不会对数据排序
使⽤LLVM(C++编写的编译器)产⽣运⾏代码,针对特定查询⽣成特定代码。
优秀的IO调度,Impala⽀持直接数据块读取和本地代码计算。 (HDFS短路读取)
选择适合的数据存储格式可以得到最好的性能(Impala⽀持多种存储格式)。
尽可能使⽤内存,中间结果不写磁盘,及时通过⽹络以stream的⽅式传递。
Impala与Hive对⽐分析
查询过程
中间结果
交互查询
计算引擎
容错
查询速度
Impala优势总结
Hive: 复杂的批处理查询任务,数据转换任务,对实时性要求不⾼同时数据量⼜很⼤的场景。
Impala:实时数据分析,与Hive配合使⽤,对Hive的结果数据集进⾏实时分析。impala不能完全取代 hive,impala可以直接处理hive表中的数据。
采用CDH安装即可。
采用CDH安装即可。
如果想要使⽤Impala ,需要将数据加载到Impala中,如何加载数据到Impala中呢?
准备数据⽂件
user.csv
392456197008193000,张三,20,0
267456198006210000,李四,25,1
892456199007203000,王五,24,1
492456198712198000,赵六,26,2
392456197008193000,张三,20,0
392456197008193000,张三,20,0
创建HDFS 存放数据的路径
hadoop fs -mkdir -p /user/impala/t1
#上传本地user.csv到hdfs /user/impala/table1
hadoop fs -put user.csv /user/impala/t1
创建表
#进⼊impala-shell
impala-shell
#表如果存在则删除
drop table if exists t1;
#执⾏创建
create external table t1(id string,name string,age int,gender int)
row format delimited fields terminated by ','
location '/user/impala/t1';
查询数据
[linux122:21000] > select * from t1;
Query: select * from t1
+--------------------+------+-----+--------+
| id | name | age | gender |
+--------------------+------+-----+--------+
| 392456197008193000 | 张三 | 20 | 0 |
| 267456198006210000 | 李四 | 25 | 1 |
| 892456199007203000 | 王五 | 24 | 1 |
| 492456198712198000 | 赵六 | 26 | 2 |
| 392456197008193000 | 张三 | 20 | 0 |
| 392456197008193000 | 张三 | 20 | 0 |
+--------------------+------+-----+--------+
创建t2表
#创建⼀个内部表
create table t2(id string,name string,age int,gender int)
row format delimited fields terminated by ',';
#查看表结构
desc t1;
desc formatted t2;
插⼊数据到t2
insert overwrite table t2 select * from t1 where gender =0;
#验证数据
select * from t2;
[linux122:21000] > select * from t2;
Query: select * from t2
+--------------------+------+-----+--------+
| id | name | age | gender |
+--------------------+------+-----+--------+
| 392456197008193000 | 张三 | 20 | 0 |
| 392456197008193000 | 张三 | 20 | 0 |
| 392456197008193000 | 张三 | 20 | 0 |
+--------------------+------+-----+--------+
更新元数据
使⽤Beeline连接Hive查看Hive中的数据,发现通过Impala创建的表,导⼊的数据都可以被Hive感 知到。
上⾯案例中Impala的数据⽂件我们准备的是以逗号分隔的⽂本⽂件,实际上,Impala可以⽀ 持RCFile,SequenceFile,Parquet等多种⽂件格式。
Impala与Hive元数据的关系?
Hive对于元数据的更新操作不能被Impala感知到;
mpala对元数据的更新操作可以被Hive感知到。
Impala同步Hive元数据命令:
⼿动执⾏invalidate metadata ,(后续详细讲解)
Impala是通过Hive的metastore服务来访问和操作Hive的元数据,但是Hive对表进⾏创建删 除修改等操作,Impala是⽆法⾃动识别到Hive中元数据的变更情况的,如果想让Impala识别 到Hive元数据的变化,所以需要进⼊impala-shell之后⾸先要做的操作就是执⾏invalidate metadata,该命令会将所有的Impala的元数据失效并重新从元数据库同步元数据信息。后⾯详细讲解元数据更新命令。
在hdfs-site.xml中添加如下配置:
<property>
<name>dfs.permissions.enabledname>
<value>falsevalue>
property>
Impala是⼀个分布式,⼤规模并⾏处理(MPP)数据库引擎,它包括多个进程。Impala与Hive类似不是数据库⽽是数据分析⼯具;
#在linux123执⾏ps -ef | grep impala
#结果
impala 29212 1 0 Jul02 ? 00:01:06
/usr/lib/impala/sbin/statestored -log_dir=/var/log/impala -
state_store_port=24000
impala 29249 1 0 Jul02 ? 00:00:49
/usr/lib/impala/sbin/catalogd -log_dir=/var/log/impala
impala 29341 1 0 Jul02 ? 00:00:49 /usr/lib/impala/sbin/impalad
-log_dir=/var/log/impala -catalog_service_host=linux123 -
state_store_port=24000 -use_statestore -state_store_host=linux123 -
be_port=22000
生成分布式的查询计划, 分配给其它节点。
namenode提供真正的元数据信息。(移动计划,而不是移动数据)
impalad
statestored
catalogd
Client提交任务
Client发送⼀个SQL查询请求到任意⼀个Impalad节点,会返回⼀个queryId⽤于之后的客户端操 作。
⽣成单机和分布式执⾏计划
SQL提交到Impalad节点之后,Analyser依次执⾏SQL的词法分析、语法分析、语义分析等操作; 从MySQL元数据库中获取元数据,从HDFS的名称节点中获取数据地址,以得到存储这个查询相关数据的所有数据节点
任务调度和分发
Coordinator将Fragment(⼦任务)根据数据分区信息发配到不同的Impalad节点上执⾏。Impalad 节点接收到执⾏Fragment请求交由Executor执⾏。
Fragment之间的数据依赖
每⼀个Fragment的执⾏输出通过DataStreamSink发送到下⼀个Fragment,Fragment运⾏过程中 不断向coordinator节点汇报当前运⾏状态。
结果汇总
查询的SQL通常情况下需要有⼀个单独的Fragment⽤于结果的汇总,它只在Coordinator节点运 ⾏,将多个节点的最终执⾏结果汇总,转换成ResultSet信息。
获取结果
客户端调⽤获取ResultSet的接⼝,读取查询结果。
以⼀个SQL例⼦来展示查询计划
SQL语句
select
t1.n1,
t2.n2,
count(1) as c
from t1 join t2 on t1.id = t2.id
join t3 on t1.id = t3.id
where t3.n3 between ‘a’ and ‘f’
group by t1.n1, t2.n2
order by c desc
limit 100;
QueryPlanner⽣成单机的执⾏计划
分析上⾯的单机执⾏计划,第⼀步先去扫描t1表中需要的数据,如果数据⽂件存储是列式存储我们可以 便利的扫描到所需的列id,n1;接着需要与t2表进⾏Join操作,扫描t2表与t1表类似获取到所需数据列 id,n2;t1与t2表进⾏关联,关联之后再与t3表进⾏关联,这⾥Impala会使⽤谓词下推扫描t3表只取join所 需数据;对group by进⾏相应的aggregation操作,最终是排序取出指定数量的数据返回。
分布式并⾏执⾏计划
所谓的分布式并⾏化执⾏计划就是在单机执⾏计划基础之上结合数据分布式存储的特点,按照任务的计 算要求把单机执⾏计划拆分为多段⼦任务,每个⼦任务都是可以并⾏执⾏的。上⾯的单机执⾏计划转为 分布式并⾏执⾏计划如下图所示:
解析:从上可以看出, T1,T2是两张大表, 因为其在两个节点上存在, t3是小表。
impala会通过对join的 id进行hash, 将数据打散分布到三个节点上(impala有几个干活的节点就可以分布到几个几点上),同时,由于t3是小表,将t3复制到三个节点上, 在三个节点join 求得值后, 再对分组字段进行hash, 打散到两个节点上(有几个分组字段就可以用几个节点并行), 在每个分组字段上求得局部的top100, 最终再求得最后的top100。(充分利用并行, 底层是使用c++语言写的)
大表进行HashJon (对join字段进行hash)
小表进行广播join。
分布式并⾏执⾏计划流程图
分布式执⾏计划中涉及到多表的Join,Impala会根据表的⼤⼩来决定Join的⽅式,主要有两种分别是Hash Join与Broadcast Join
上⾯分布式执⾏计划中可以看出T1,T2表⼤⼀些,⽽T3表⼩⼀些,所以对于T1与T2的Join Impala选择使 ⽤Hash Join,对于T3表选择使⽤Broadcast ⽅式,直接把T3表⼴播到需要Join的节点上。
分布式并⾏计划流程
T1和T2使⽤Hash join,此时需要按照id的值分别将T1和T2分散到不同的Impalad进程,但是相同 的id会散列到相同的Impalad进程,这样每⼀个Join之后是全部数据的⼀部分
T1与T2Join之后的结果数据再与T3表进⾏Join,此时T3表采⽤Broadcast⽅式把⾃⼰全部数据(id列) ⼴播到需要的Impala节点上
T1,T2,T3Join之后再根据Group by执⾏本地的预聚合,每⼀个节点的预聚合结果只是最终结果的⼀部分(不同的节点可能存在相同的group by的值),需要再进⾏⼀次全局的聚合。
全局的聚合同样需要并⾏,则根据聚合列进⾏Hash分散到不同的节点执⾏Merge运算(其实仍然 是⼀次聚合运算),⼀般情况下为了较少数据的⽹络传输, Impala会选择之前本地聚合节点做全 局聚合⼯作。
通过全局聚合之后,相同的key只存在于⼀个节点,然后对于每⼀个节点进⾏排序和TopN计算,最 终将每⼀个全局聚合节点的结果返回给Coordinator进⾏合并、排序、limit计算,返回结果给⽤户
Impala的核⼼开发语⾔是sql语句,Impala有shell命令⾏窗⼝,以及JDBC等⽅式来接收sql语句执⾏, 对于复杂类型分析可以使⽤C++或者Java来编写UDF函数。
Impala的sql语法是⾼度集成了Apache Hive的sql语法,Impala⽀持Hive⽀持的数据类型以及部分Hive 的内置函数。
需要注意的⼏点:
所谓的外部命令指的是不需要进⼊到impala-shell交互命令⾏当中即可执⾏的命令参数。impala-shell后 ⾯执⾏的时候可以带很多参数。你可以在启动 impala-shell 时设置,⽤于修改命令执⾏环境。
impala-shell –h可以帮助我们查看帮助⼿册。
⽐如⼏个常⻅的:
impala-shell –r刷新impala元数据,与建⽴连接后执⾏ REFRESH 语句效果相同(元数据发⽣变化的时候)
impala-shell –f ⽂件路径 执⾏指的的sql查询⽂件。
impala-shell –i指定连接运⾏ impalad 守护进程的主机。默认端⼝是 21000。你可以连接到集群中运⾏ impalad 的任意主机。
impala-shell –o保存执⾏结果到⽂件当中去。
展示Impala默认⽀持的内置函数需要进⼊Impala默认系统数据库(也就是_impala_builtins)中执⾏
use _impala_builtins;
show functions;
在其它数据库下⽆法查看!!
所谓内部命令是指,进⼊impala-shell命令⾏之后可以执⾏的语法
connect hostname 连接到指定的机器impalad上去执⾏。
refresh dbname.tablename增量刷新,刷新某⼀张表的元数据,主要⽤于刷新hive当中数据表⾥⾯的 数据改变的情况。
invalidate metadata全量刷新,性能消耗较⼤,主要⽤于hive当中新建数据库或者数据库表的时候来进 ⾏刷新。
quit/exit命令 从Impala shell中退出
explain 命令 ⽤于查看sql语句的执⾏计划
explain的值可以设置成0,1,2,3等⼏个值,其中3级别是最⾼的,可以打印出最全的信息
set explain_level=3;
profile命令执⾏sql语句之后执⾏,可以
打印出更加详细的执⾏步骤,主要⽤于查询结果的查看,集群的调优等。
expalin:可以不真正执⾏任务,只是展示任务的执⾏计划;
profile:需要任务执⾏完成后调⽤,可以从更底层以及更详细的层⾯来观察我们运⾏impala的任务,进 ⾏调优。
创建数据库
CREATE DATABASE语句⽤于在Impala中创建新数据库。
CREATE DATABASE IF NOT EXISTS database_name;
这⾥,IF NOT EXISTS是⼀个可选的⼦句。如果我们使⽤此⼦句,则只有在没有具有相同名称的现有数 据库时,才会创建具有给定名称的数据库。
默认就会在hive的数仓路径下创建新的数据库名⽂件夹
/user/hive/warehouse/lagoutest.db
删除数据库
Impala的DROP DATABASE语句⽤于从Impala中删除数据库。 在删除数据库之前,建议从中删除所有 表。
如果使⽤级联删除,Impala会在删除指定数据库中的表之前删除它。
drop database sample cascade;
create table语句
CREATE TABLE语句⽤于在Impala中的所需数据库中创建新表。 需要指定表名字并定义其列和每列的数 据类型。
impala⽀持的数据类型和hive类似
默认建表的数据存储路径跟hive⼀致。也可以在建表的时候通过location指定具体路径。
insert 语句
Impala的INSERT语句有两个⼦句: into和overwrite。into⽤于插⼊新记录数据,overwrite⽤于覆盖已 有的记录。
insert into table_name (column1, column2, column3,...columnN)values (value1,
value2, value3,...valueN);
Insert into table_name values (value1, value2, value2);
这⾥,column1,column2,… columnN是要插⼊数据的表中的列的名称。还可以添加值⽽不指定列 名,但是,需要确保值的顺序与表中的列的顺序相同。
例⼦
create table employee (Id INT, name STRING, age INT,address STRING, salary
BIGINT);
insert into employee VALUES (1, 'Ramesh', 32, 'Ahmedabad', 20000 );
insert into employee values (2, 'Khilan', 25, 'Delhi', 15000 );
Insert into employee values (3, 'kaushik', 23, 'Kota', 30000 );
Insert into employee values (4, 'Chaitali', 25, 'Mumbai', 35000 );
Insert into employee values (5, 'Hardik', 27, 'Bhopal', 40000 );
Insert into employee values (6, 'Komal', 22, 'MP', 32000 );
overwrite覆盖⼦句覆盖表当中全部记录。 覆盖的记录将从表中永久删除。
Insert overwrite employee values (1, 'Ram', 26, 'Vishakhapatnam', 37000 );
select语句
Impala SELECT语句⽤于从数据库查询数据, 此查询以表的形式返回数据。
describe 语句
Impala中的describe语句⽤于提供表的描述。 此语句的结果包含有关表的信息,例如列名称及其数据 类型
alter table
Impala中的Alter table语句⽤于对给定表执⾏更改。使⽤此语句,我们可以添加,删除或修改现有表中 的列,也可以重命名它们。
delete、truncate table
Impala drop table语句⽤于删除Impala中的现有表。此语句还会删除内部表的底层HDFS⽂件。
注意:使⽤此命令时必须⼩⼼,因为删除表后,表中可⽤的所有信息也将永远丢失。
Impala的Truncate Table语句⽤于从现有表中删除所有记录。保留表结构。
您也可以使⽤DROP TABLE命令删除⼀个完整的表,但它会从数据库中删除完整的表结构,如果您希望 存储⼀些数据,您将需要重新创建此表。
drop table database_name.table_name;
truncate table_name;
Impala对复杂数据类型的⽀持
对于Text存储格式中的复杂类型不⽀持,复杂类型要使⽤parquet格式。
view视图
视图仅仅是存储在数据库中具有关联名称的Impala查询语⾔的语句。 它是以预定义的SQL查询形式的表 的组合。
视图可以包含表的所有⾏或选定的⾏。
create view if not exists view_name as select statement
创建视图view、查询视图view
create view if not exists employee_view AS select name, age from employee;
修改视图
alter view database_name.view_name as Select语句
删除视图
drop view database_name.view_name;
order by⼦句
Impala ORDER BY⼦句⽤于根据⼀个或多个列以升序或降序对数据进⾏排序。 默认情况下,⼀些数据库按升序对查询结果进⾏排序。
select * from table_name ORDER BY col_name
[ASC|DESC] [NULLS FIRST|NULLS LAST]
可以使⽤关键字ASC或DESC分别按升序或降序排列表中的数据。
如果我们使⽤NULLS FIRST,表中的所有空值都排列在顶⾏; 如果我们使⽤NULLS LAST,包含空值的⾏ 将最后排列。
group by⼦句
Impala GROUP BY⼦句与SELECT语句协作使⽤,以将相同的数据排列到组中。
select name, sum(salary) from employee group by name;
having⼦句
容易与where过滤进⾏混淆,
如何区分:
where:过滤的数据是原始数据,表中本来就存在的数据;
having:过滤的是查询结果数据;
按年龄对表进⾏分组,并选择每个组的最⼤⼯资,并显示⼤于20000的⼯资
limit、offset
Impala中的limit⼦句⽤于将结果集的⾏数限制为所需的数,即查询的结果集不包含超过指定限制的记录。
⼀般来说,select查询的resultset中的⾏从0开始。使⽤offset⼦句,我们可以决定从哪⾥考虑输出。
select * from employee order by salary limit 2 offset 2;
使⽤offset关键字要求结果数据必须是排序之后的!!
insert into values
这种⽅式⾮常类似于RDBMS的数据插⼊⽅式。
create table t_test2(id int,name string);
insert into table t_test2 values(1,”zhangsan”);
insert into select
插⼊⼀张表的数据来⾃于后⾯的select查询语句返回的结果。
create table as select
建表的字段个数、类型、数据来⾃于后续的select查询语句
load data⽅式,这种⽅式不建议在Impala中使⽤,先使⽤load data⽅式把数据加载到Hive表中,然后 使⽤以上⽅式插⼊Impala表中。
在实际⼯作当中,因为impala的查询⽐较快,所以可能有会使⽤到impala来做数据库查询的情况,我们可以通过java代码来进⾏操作impala的查询
<dependencies>
<dependency>
<groupId>org.apache.hadoopgroupId>
<artifactId>hadoop-commonartifactId>
<version>2.9.2version>
dependency>
<dependency>
<groupId>org.apache.hivegroupId>
<artifactId>hive-commonartifactId>
<version>2.3.7version>
dependency>
<dependency>
<groupId>org.apache.hivegroupId>
<artifactId>hive-metastoreartifactId>
<version>2.3.7version>
dependency>
<dependency>
<groupId>org.apache.hivegroupId>
<artifactId>hive-serviceartifactId>
<version>2.3.7version>
dependency>
<dependency>
<groupId>org.apache.hivegroupId>
<artifactId>hive-jdbcartifactId>
<version>2.3.7version>
dependency>
<dependency>
<groupId>org.apache.hivegroupId>
<artifactId>hive-execartifactId>
<version>2.3.7version>
dependency>
dependencies>
package com.my.impala.jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
public class ImpalaTest {
public static void main(String[] args) throws Exception {
//定义连接impala的驱动和连接url
String driver = "org.apache.hive.jdbc.HiveDriver";
String driverUrl = "jdbc:hive2://linux123:25004/default;auth=noSasl";
//查询的sql语句
String querySql = "select * from t1";
//获取连接
Class.forName(driver);
//通过Drivermanager获取连接
final Connection connection = DriverManager.getConnection(driverUrl);
final PreparedStatement ps = connection.prepareStatement(querySql);
//执行查询
final ResultSet resultSet = ps.executeQuery();
//解析返回结果
//获取到每条数据的列数
final int columnCount = resultSet.getMetaData().getColumnCount();
//遍历结果集
while (resultSet.next()) {
for (int i = 1; i <= columnCount; i++) {
final String string = resultSet.getString(i);
System.out.print(string + "\t");
}
System.out.println();
}
//关闭资源
ps.close();
connection.close();
}
}
Impala主要有三个组件,分别是statestore,catalog和impalad,对于Impalad节点,每⼀个节点都可 以接收客户端的查询请求,并且对于连接到该Impalad的查询还要作为Coordinator节点(需要消耗⼀ 定的内存和CPU)存在,为了保证每⼀个节点的资源开销的平衡需要对于集群中的Impalad节点做⼀下 负载均衡.
DNS做负载均衡⽅案是最简单的,但是性能⼀般,所以这⾥我们按照官⽅的建议使⽤HAProxy实现负载 均衡
⽣产中应该选择⼀个⾮Impalad节点作为HAProxy的安装节点
安装haproxy
yum install haproxy -y
配置⽂件
vim /etc/haproxy/haproxy.cfg
具体配置内容
启动
开启: service haproxy start
关闭: service haproxy stop
重启: service haproxy restart
使⽤
Impala-shell访问⽅式
impala-shell -i linux123:25003
使⽤起来⼗分⽅便,区别仅仅相当于是修改了⼀个ip地址和端⼝⽽已,其余不变。
jdbc:hive2://linux123:25004/default;auth=noSasl
Impala集群在操作过程中尽量多给内存,如果内存不能满⾜使⽤要求,Impala的执⾏很可能会报错!!
cloudera官⽹上的Impala⽂档,原名为《Impala Performance Guidelines and Best Practices》。主 要介绍了为了提升impala性能应该考虑的⼀些事情,结合实际考虑:
基本优化策略
⽂件格式 :对于⼤数据量来说,Parquet⽂件格式是最佳的
避免⼩⽂件: insert … values 会产⽣⼤量⼩⽂件,避免使⽤
合理分区粒度
利⽤分区可以在查询的时候忽略掉⽆⽤数据,提⾼查询效率,通常建议分区数量在3万以下 (太多的分区也会造成元数据管理的性能下降)
分区列数据类型最好是整数类型
分区列可以使⽤string类型,因为分区列的值最后都是作为HDFS⽬录使⽤,如果分区列使⽤整数类型可以降低内存消耗
获取表的统计指标:在追求性能或者⼤数据量查询的时候,要先获取所需要的表的统计指标 (如:执⾏ compute stats )
减少传输客户端数据量
聚合(如 count、sum、max 等)
过滤(如 WHERE )
limit限制返回条数
返回结果不要使⽤美化格式进⾏展示(在通过impala-shell展示结果时,添加这些可选参数: - B、 --output_delimiter )
在执⾏之前使⽤EXPLAIN来查看逻辑规划,分析执⾏逻辑
Impala join⾃动的优化⼿段就是通过使⽤COMPUTE STATS来收集参与Join的每张表的统计信 息,然后由Impala根据表的⼤⼩、列的唯⼀值数⽬等来⾃动优化查询。为了更加精确地获取 每张表的统计信息,每次表的数据变更时(如执⾏Insert,add partition,drop partition等)最好都要执⾏⼀遍COMPUTE STATS获取到准确的表统计信息。
pics/impala_perf_cookbook.html)》。主 要介绍了为了提升impala性能应该考虑的⼀些事情,结合实际考虑:
基本优化策略
⽂件格式 :对于⼤数据量来说,Parquet⽂件格式是最佳的
避免⼩⽂件: insert … values 会产⽣⼤量⼩⽂件,避免使⽤
合理分区粒度
利⽤分区可以在查询的时候忽略掉⽆⽤数据,提⾼查询效率,通常建议分区数量在3万以下 (太多的分区也会造成元数据管理的性能下降)
分区列数据类型最好是整数类型
分区列可以使⽤string类型,因为分区列的值最后都是作为HDFS⽬录使⽤,如果分区列使⽤整数类型可以降低内存消耗
获取表的统计指标:在追求性能或者⼤数据量查询的时候,要先获取所需要的表的统计指标 (如:执⾏ compute stats )
减少传输客户端数据量
聚合(如 count、sum、max 等)
过滤(如 WHERE )
limit限制返回条数
返回结果不要使⽤美化格式进⾏展示(在通过impala-shell展示结果时,添加这些可选参数: - B、 --output_delimiter )
在执⾏之前使⽤EXPLAIN来查看逻辑规划,分析执⾏逻辑
Impala join⾃动的优化⼿段就是通过使⽤COMPUTE STATS来收集参与Join的每张表的统计信 息,然后由Impala根据表的⼤⼩、列的唯⼀值数⽬等来⾃动优化查询。为了更加精确地获取 每张表的统计信息,每次表的数据变更时(如执⾏Insert,add partition,drop partition等)最好都要执⾏⼀遍COMPUTE STATS获取到准确的表统计信息。