主要内容
第 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分析,+1天分析,今天分析昨天的数据),实时处理理(数据到来即分析),数据可视化,机器器学习,深度学习等。
⾯面对如此众多的阶段再加上⼤大数据天⽣生的⼤大数据量量问题没有任何⼀一个框架可以完美cover以上每个阶段。所以⼤大数据领域有⾮非常多框架,每个框架都有最适合⾃自⼰己的具体场景。⽐比如: HDFS负责⼤大数据量量存储, MapReduce(Hive)负责⼤数据量的分析计算。
Impala的诞⽣生
之前学习的Hive以及MR适合离线批处理理,但是对交互式查询的场景⽆无能为⼒力力(要求快速响应),所以为了了解决查询速度的问题, Cloudera公司依据Google的Dremel开发了了Impala,Impala抛弃了了MapReduce使⽤了类似于传统的MPP数据库技术,⼤大提⾼高了了查询的速度。
MPP是什么?
MPP (Massively Parallel Processing),就是⼤大规模并行处理理,在MPP集群中,每个节点资源都是独立享有也就是有独⽴立的磁盘和内存,每个节点通过⽹网络互相连接,彼此协同计算,作为整体提供数据服务。
简单来说, MPP是将任务并行的分散到多个服务器器和节点上,在每个节点上计算完成后,将各⾃自部分的结果汇总在⼀一起得到最终的结果。
对于MPP架构的软件来说聚合操作⽐比如计算某张表的总条数,则先进行局部聚合(每个节点并行计算),然后把局部汇总结果进行全局聚合(与Hadoop相似)。
Impala与Hive对比
Impala的技术优势
Impala与Hive对⽐分析
查询过程
中间结果
交互查询
计算引擎
容错
查询速度
Impala优势总结
Hive: 复杂的批处理理查询任务,数据转换任务,对实时性要求不⾼高同时数据量又很大的场景。
Impala:实时数据分析,与Hive配合使用,对Hive的结果数据集进行实时分析。 impala不能完全取代hive, impala可以直接处理hive表中的数据。
准备Impala的所有依赖包
Cloudera公司对于Impala的安装只提供了rpm包没有提供tar包;所以我们选择使⽤Cloudera的rpm包进⾏Impala的安装,但是另外⼀个问题,Impala的rpm包依赖⾮常多的其他的rpm包,我们可以⼀个个的将依赖找出来,但是这种⽅式实在是浪费时间。
Linux系统中对于rpm包的依赖管理提供了⼀个⾮常好的管理⼯具叫做Yum,类似于Java⼯程中的包管理⼯具Maven,Maven可以⾃动搜寻指定Jar所需的其它依赖并⾃动下载来。Yum同理可以⾮常⽅便的让我们进⾏rpm包的安装⽆需关系当前rpm所需的依赖。但是与Maven下载其它依赖需要到中央仓库⼀样Yum下载依赖所需的源也是在放置在国外服务器并且其中没有安装Impala所需要的rpm包,所以默认的这种Yum源可能下载依赖失败。所以我们可以⾃⼰指定Yum去哪⾥下载所需依赖。
rpm⽅式安装:需要⾃⼰管理rpm包的依赖关系;⾮常麻烦;解决依赖关系使⽤yum;默认Yum源是没有Impala的rpm安装包,所以我们⾃⼰准备好所有的Impala安装所需的rpm包,制作Yum本地源,配置Yum命令去到我们准备的Yun源中下载Impala的rpm包进⾏安装。
Yum命令默认源
本地Yum源⽅式
具体制作步骤
Yum源是Centos当中下载软件rpm包的地址,因此通过制作本地Yum源并指定Yum命令使⽤本地Yum源,为了使Yum命令(本机,跨⽹络节点)可以通过⽹络访问到本地源,我们使⽤Httpd这种静态资源服务器来开放我们下载所有的rpm包。
#yum⽅式安装httpd服务器
yum install httpd -y
#启动httpd服务器
systemctl start httpd
#验证httpd⼯作是否正常,默认端⼝是80,可以省略
http://centos7-1:80
<html> <div style="font-size:100px">
this is a new page!!
div>
html>
访问 test.html:http://centos7-1/test.html
ln -s /opt/lagou/software/cdh/5.7.6 /var/www/html/cdh57
验证:http://centos7-1/cdh57/
如果提示403 forbidden,修改config文件
vim /etc/selinux/config
## 将SELINUX=enforcing 改为 disabled
cd /etc/yum.repos.d
#创建⼀个新的配置⽂件
vim local.repo
#添加如下内容
[local]
name=local
baseurl=http://centos7-1/cdh57/
gpgcheck=0
enabled=1
name:对于当前源的描述
baseurl:访问当前源的地址信息
gpgcheck: 1 0,gpg校验
enabled:1/0,是否使⽤当前源
scp local.repo centos7-2:$PWD
scp local.repo centos7-3:$PWD
centos7-3
yum install impala -y
yum install impala-server -y
yum install impala-state-store -y
yum install impala-catalog -y
yum install impala-shell -y
centos7-1与centos7-2
yum install impala-server -y
yum install impala-shell -y
配置Impala
vim hive-site.xml
<property>
<name>hive.metastore.urisname>
<value>thrift://linux121:9083,thrift://linux123:9083value>
property>
<property>
<name>hive.metastore.client.socket.timeoutname>
<value>3600value>
property>
nohup hive --service metastore &
nohup hive --service hiveserver2 &
# 1.创建短路读取本地中转站
#所有节点创建⼀下⽬录
mkdir -p /var/lib/hadoop-hdfs
# 2.修改hdfs-site.xml
<!--添加如下内容 -->
<!--打开短路读取开关 -->
<!-- 打开短路读取配置-->
<property>
<name>dfs.client.read.shortcircuit</name>
<value>true</value>
</property>
<!--这是⼀个UNIX域套接字的路径,将⽤于DataNode和本地HDFS客户机之间的通信 -->
<property>
<name>dfs.domain.socket.path</name>
<value>/var/lib/hadoop-hdfs/dn_socket</value>
</property>
<!--block存储元数据信息开发开关 -->
<property>
<name>dfs.datanode.hdfs-blocks-metadata.enabled</name>
<value>true</value>
</property>
<property>
<name>dfs.client.file-block-storage-locations.timeout</name>
<value>30000</value>
</property>
注:分发到集群其它节点。重启Hadoop集群。
rm -rf /etc/impala/conf/core-site.xml
rm -rf /etc/impala/conf/hdfs-site.xml
rm -rf /etc/impala/conf/hive-site.xml
ln -s /opt/lagou/servers/hadoop-2.9.2/etc/hadoop/core-site.xml /etc/impala/conf/core-site.xml
ln -s /opt/lagou/servers/hadoop-2.9.2/etc/hadoop/hdfs-site.xml /etc/impala/conf/hdfs-site.xml
ln -s /opt/lagou/servers/hive-2.3.7/conf/hive-site.xml /etc/impala/conf/hive-site.xml
Impala⾃身配置
所有节点更改Impala默认配置⽂件以及添加mysql的驱动包
vim /etc/default/impala
<!--更新如下内容 -->
IMPALA_CATALOG_SERVICE_HOST=centos7-3
IMPALA_STATE_STORE_HOST=centos7-3
所有节点创建mysql的驱动包的软链接
#创建节点
mkdir -p /usr/share/java
ln -s /opt/lagou/servers/hive-2.3.7/lib/mysql-connector-java-5.1.49.jar /usr/share/java/mysql-connector-java.jar
修改bigtop的java_home路径(打包测试的工具,依赖于java)
注意:Apache Bigtop 是⼀个针对基础设施⼯程师和数据科学家的开源项⽬,旨在全⾯打包、测试和配置领先的开源⼤数据组件/项⽬。Impala项⽬中使⽤到了此软件。
vim /etc/default/bigtop-utils
export JAVA_HOME=/opt/lagou/servers/jdk1.8.0_231
启动Impala
#linux123启动如下⻆⾊
service impala-state-store start
service impala-catalog start
service impala-server start
#其余节点启动如下⻆⾊
service impala-server start
#查看是否启动成功
ps -ef | grep impala
## /var/log/impala/目录下存放了impala的日志信息
#浏览器Web界⾯验证
#访问impalad的管理界⾯
http://centos7-3:25000/
#访问statestored的管理界⾯
http://centos7-3:25010/
消除Impala影响
由于使⽤Yum命令安装Impala,我们选择使⽤yum⾃动进⾏Impala依赖的安装和处理,所以本次安装默认会把Impala依赖的所有框架都会安装,⽐如Hadoop,Hive,Mysql等,为了保证我们⾃⼰安装的Hadoop等使⽤正常我们需要删除掉Impala默认安装的其它框架
[root@linux122 conf]# which hadoop
/usr/bin/hadoop
[root@linux122 conf]# which hive
/usr/bin/hive
#使⽤which命令 查找hadoop,hive等会发现,命令⽂件是/usr/bin/hadoop ⽽⾮我们⾃⼰安装的路
径,需要把这些删除掉,所有节点都要执⾏
rm -rf /usr/bin/hadoop
rm -rf /usr/bin/hdfs
rm -rf /usr/bin/hive
rm -rf /usr/bin/beeline
rm -rf /usr/bin/hiveserver2
#重新⽣效环境变量
source /etc/profile
使用Yum方式安装Impala后, impala-shell可以全局使用;进入impala-shell命令行impala-shell进⼊入到impala的交互窗口
392456197008193000,张三,20,0
267456198006210000,李四,25,1
892456199007203000,王五,24,1
492456198712198000,赵六,26,2
392456197008193000,张三,20,0
392456197008193000,张三,20,0
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';
#创建⼀个内部表
create table t2(id string,name string,age int,gender int)
row format delimited fields terminated by ','; #查看表结构
desc t1;
desc formatted t2;
insert overwrite table t2 select * from t1 where gender =0; #验证数据
select * from t2;
更新元数据
使⽤Beeline连接Hive查看Hive中的数据,发现通过Impala创建的表,导⼊的数据都可以被Hive感知到。
⼩结:
<property>
<name>dfs.permissions.enabledname>
<value>falsevalue>
property>
Impala是⼀个分布式,⼤规模并⾏处理(MPP)数据库引擎,它包括多个进程。Impala与Hive类似不是数据库⽽是数据分析⼯具;
impalad
statestored
catalogd
查询计划示例
以⼀个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操作,最终是排序取出指定数量的数据返回。
分布式并⾏执⾏计划
所谓的分布式并⾏化执⾏计划就是在单机执⾏计划基础之上结合数据分布式存储的特点,按照任务的计算要求把单机执⾏计划拆分为多段⼦任务,每个⼦任务都是可以并⾏执⾏的。上⾯的单机执⾏计划转为分布式并⾏执⾏计划如下图所示:
分布式执⾏计划中涉及到多表的Join,Impala会根据表的⼤⼩来决定Join的⽅式,主要有两种分别是HashJoin与Broadcast Join。
上⾯分布式执⾏计划中可以看出T1,T2表⼤⼀些,⽽T3表⼩⼀些,所以对于T1与T2的Join Impala选择使⽤Hash Join,对于T3表选择使⽤Broadcast ⽅式,直接把T3表⼴播到需要Join的节点上。
分布式并⾏计划流程
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默认系统数据库中执⾏。
show functions;
所谓内部命令是指,进⼊impala-shell命令⾏之后可以执⾏的语法。
/user/hive/warehouse/lagoutest.db
drop database sample cascade;
create table IF NOT EXISTS database_name.table_name ( column1 data_type, column2 data_type, column3 data_type, ……… columnN data_type);
CREATE TABLE IF NOT EXISTS my_db.student(name STRING, age INT, contact INT );
默认建表的数据存储路径跟hive⼀致。也可以在建表的时候通过location指定具体路径。
insert into table_name (column1, column2, column3,...columnN)values (value1,
value2, value3,...valueN);
Insert into table_name values (value1, value2, value2);
这⾥,column1,column2,… columnN是要插⼊数据的表中的列的名称。还可以添加值⽽不指定列名,但是,需要确保值的顺序与表中的列的顺序相同。
overwrite覆盖⼦句覆盖表当中全部记录。 覆盖的记录将从表中永久删除。
drop table database_name.table_name;
Impala的Truncate Table语句⽤于从现有表中删除所有记录。保留表结构。
您也可以使⽤DROP TABLE命令删除⼀个完整的表,但它会从数据库中删除完整的表结构,如希望存储⼀些数据,您将需要重新创建此表。
truncate table_name;
对于Text存储格式中的复杂类型不⽀持,复杂类型要使⽤parquet格式。
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;
select * from table_name ORDER BY col_name
[ASC|DESC] [NULLS FIRST|NULLS LAST]
可以使⽤关键字ASC或DESC分别按升序或降序排列表中的数据。
如果我们使⽤NULLS FIRST,表中的所有空值都排列在顶⾏; 如果我们使⽤NULLS LAST,包含空值的⾏将最后排列。
select max(salary) from employee group by age having max(salary) > 20000;
select * from employee order by salary limit 2 offset 2;
使⽤offset关键字要求结果数据必须是排序之后的!
create table t_test2(id int,name string);
insert into table t_test2 values(1,”zhangsan”);
在实际⼯作当中,因为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.lagou.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://linux122:21050/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节点做⼀下负载均衡。
安装haproxy
yum install haproxy -y
配置⽂件
vim /etc/haproxy/haproxy.cfg
listen status #定义管理界⾯
bind 0.0.0.0:1080 #管理界⾯访问IP和端⼝
mode http #管理界⾯所使⽤的协议
option httplog
maxconn 5000 #最⼤连接数
stats refresh 30s #30秒⾃动刷新
stats uri /stats
listen impalashell
bind 0.0.0.0:25003 #ha作为proxy所绑定的IP和端⼝
mode tcp #以4层⽅式代理,重要
option tcplog
balance roundrobin #调度算法 'leastconn' 最少连接数分配,或者 'roundrobin',轮询分
server impalashell_1 centos7-1:21000 check
server impalashell_2 centos7-2:21000 check
server impalashell_3 centos7-3:21000 check
listen impalajdbc
bind 0.0.0.0:25004 #ha作为proxy所绑定的IP和端⼝
mode tcp #以4层⽅式代理,重要
option tcplog
balance roundrobin #调度算法 'leastconn' 最少连接数分配,或者 'roundrobin',轮询分
server impalajdbc_1 centos7-1:21050 check
server impalajdbc_2 centos7-2:21050 check
server impalajdbc_3 centos7-2:21050 check
#---------------------------------------------------------------------
# main frontend which proxys to the backends
#---------------------------------------------------------------------
启动
#开启:
service haproxy start
#关闭:
service haproxy stop
#重启:
service haproxy restart
使⽤
Impala-shell访问⽅式
impala-shell -i centos7-3:25003
Impala集群在操作过程中尽量多给内存,如果内存不能满⾜使⽤要求,Impala的执⾏很可能会报错
cloudera官⽹上的Impala⽂档,原名为《Impala Performance Guidelines and Best Practices》。主要介绍了为了提升impala性能应该考虑的⼀些事情,结合实际考虑:
基本优化策略