四、Impala的使用
Impala的核心开发语言是sql语句,Impala有shell命令行窗口,以及JDBC等方式来接收sql语句执行,对于复杂类型分析可以使用C++或者Java(生产环境中常使用C++编写)来编写UDF函数。
Impala的sql语法是高度集成了Apache Hive的sql语法,Impala支持Hive支持的数据类型以及部分Hive的内置函数
需要注意的几点:
- Impala与Hive类似,它们的重点都是查询,所以像Update、delete等具有更新性质的操作最好不要使用这种工具,对于删除数据的操作可以通过Drop Table、Alter Table Drop Partition 来实现,更新可以尝试使用 Insert overwrite 方式
- 通常使用 Impala的方式是数据文件存储在Hdfs文件系统,借助于Impala的表定义来查询和管理Hdfs上的数据文件
- Impala的使用大多数与Hive相同,比如Impala同样支持内外部表,以及分区等,可以借鉴参考Hive的使用
1、Impala-shell 的命令参数
Impala-shell 外部命令
所谓的外部命令指的是不需要进入到impala-shell交互命令行当中即可执行的命令参数。impala-shell后面执行的时候可以带很多参数。你可以在启动 impala-shell 时设置,用于修改命令执行环境。
impala-shell –h
- 可以帮助我们查看帮助手册
impala-shell –r
- 刷新impala元数据,与建立连接后执行 REFRESH 语句效果相同(元数据发生变化的时候)
impala-shell –f 文件路径
- 执行指定的sql查询文件
impala-shell –i 主机名
- 如:
impala-shell -i linux123
,在linux122中执行此命令,则会打开linux123的impalad服务 - 指定连接运行impalad守护进程的主机。默认端口是 21000。你可以连接到集群中运行 impalad 的任意主机
- 如:
impala-shell –o
- 保存执行结果到文件当中去
show functions;
所谓内部命令是指,进入impala-shell命令行之后可以执行的语法
help;
可以查看内部的所有可用命令,如下图所示
- 更新元数据信息
invalidate metadata
- 全量更新,性能消耗大,不推荐,主要用于hive当中新建数据库或者数据库表的时候来进行刷新
refresh 数据库名.表名
- 增量刷新,刷新某一张表的元数据,主要用于刷新hive当中数据表里面的数据改变的情况(推荐)
connect Impalad主机名;
- 连接到指定机器的impalad 上去执行
quit/exit
- 从Impala shell中退出
explain
- 用于查看sql语句的执行计划
- 如
explain select * from t1;
- 注:explain的值可以设置成
0,1,2,3
等几个值,其中3级别是最高的,可以打印出最全的信息profile- 如
set explain_level=3;
- profile
- 如
- 在执行sql语句之后执行,可以打印出更加详细的执行步骤,主要用于查询结果的查看,集群的调优等
- 如
select * from t1;
profile;
对比 explain 和 profile
建表、删表与hive相同
impala创建数据库后,默认就会在hive的数仓路径下创建新的数据库名文件夹
impala 对于 Text 存储格式中的复杂类型(如map、array)不支持,复杂类型要使用parquet格式
view 视图
- 视图仅仅是存储在数据库中具有关联名称的Impala查询语言的语句,它是以预定义的SQL查询形式的表的组合
- 创建视图:
create view if not exists view_name as select statement;
- 查询视图:
select * from view_name;
- 修改视图:
alter view database_name.view_name as select statement;
- 删除视图:
drop view database_name.view_name;
- 创建视图:
- 视图仅仅是存储在数据库中具有关联名称的Impala查询语言的语句,它是以预定义的SQL查询形式的表的组合
limit、offset
insert into values
insert into select
create table as select
load data
方式
(不推荐)- 这种方式不建议在Impala中使用,先使用 load data 方式把数据加载到 Hive 表中,然后使用以上方式插入 Impala 表中
五、Impala的JDBC查询方式
在实际工作当中,因为impala的查询比较快,所以可能有会使用到impala来做数据库查询的情况,我们可以通过java代码来进行操作impala的查询
1、导入Jar包
<dependencies>
<!-- https://mvnrepository.com/artifact/org.apache.hadoop/hadoop-common -->
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>2.9.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.hive/hive-common -->
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-common</artifactId>
<version>2.3.7</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.hive/hive-metastore -->
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-metastore</artifactId>
<version>2.3.7</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.hive/hive-service -->
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-service</artifactId>
<version>2.3.7</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.hive/hive-jdbc -->
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-jdbc</artifactId>
<version>2.3.7</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.hive/hive-exec -->
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-exec</artifactId>
<version>2.3.7</version>
</dependency>
</dependencies>
2、Java代码开发
```java 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();
}
}
<a name="mtwW4"></a>
# 六、Impala进阶
<a name="PhVcY"></a>
## 1、Impala 负载均衡
Impala主要有三个组件,分别是statestore,catalog和impalad,对于Impalad节点,每一个节点都可以接收客户端的查询请求,并且对于连接到该Impalad的查询还要作为Coordinator节点(需要消耗一定的内存和CPU)存在,为了保证每一个节点的资源开销的平衡需要对于集群中的Impalad节点做一下负载均衡.
- Cloudera官方推荐的代理方案:**HAProxy**
- DNS做负载均衡
- DNS做负载均衡方案是最简单的,但是性能一般,所以这里我们按照官方的建议使用HAProxy实现负载均衡
- **注:生产中应该选择一个非Impalad节点作为HAProxy的安装节点!!!**
- 即 单独拿一台机器作为 负载均衡 的节点
---
在学习阶段,由于资源比较有限,因此将 HAProxy 安装在 linux123上
<a name="ItRGT"></a>
### HAProxy方案
**安装haproxy**
- `yum install haproxy -y`
**配置文件**
- `vim /etc/haproxy/haproxy.cfg`
- 在该配置文件添加内容(以 #********包括的内容),其他的内容不要动
```xml
#---------------------------------------------------------------------
# Example configuration for a possible web application. See the
# full configuration options online.
#
# http://haproxy.1wt.eu/download/1.4/doc/configuration.txt
#
#---------------------------------------------------------------------
#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
global
# to have these messages end up in /var/log/haproxy.log you will
# need to:
#
# 1) configure syslog to accept network log events. This is done
# by adding the '-r' option to the SYSLOGD_OPTIONS in
# /etc/sysconfig/syslog
#
# 2) configure local2 events to go to the /var/log/haproxy.log
# file. A line like the following can be added to
# /etc/sysconfig/syslog
#
# local2.* /var/log/haproxy.log
#
log 127.0.0.1 local2
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy
group haproxy
daemon
# turn on stats unix socket
stats socket /var/lib/haproxy/stats
#---------------------------------------------------------------------
# common defaults that all the 'listen' and 'backend' sections will
# use if not designated in their block
#---------------------------------------------------------------------
defaults
mode http
log global
option httplog
option dontlognull
option http-server-close
option forwardfor except 127.0.0.0/8
option redispatch
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 3000
# *********************************************************************
# *********************************************************************
listen impalashell
bind 0.0.0.0:25003 #ha作为proxy所绑定的IP和端口
mode tcp#以4层方式代理,重要
option tcplog
balance roundrobin #调度算法 'leastconn' 最少连接数分配,或者 'roundrobin',轮询分配
server impalashell_1 linux121:21000 check
server impalashell_2 linux122:21000 check
server impalashell_3 linux123: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 linux121:21050 check
server impalajdbc_2 linux122:21050 check
server impalajdbc_3 linux122:21050 check
# *********************************************************************
# *********************************************************************
#---------------------------------------------------------------------
# main frontend which proxys to the backends
#---------------------------------------------------------------------
frontend main *:5000
acl url_static path_beg -i /static /images /javascript /stylesheets
acl url_static path_end -i .jpg .gif .png .css .js
use_backend static if url_static
default_backend app
#---------------------------------------------------------------------
# static backend for serving up images, stylesheets and such
#---------------------------------------------------------------------
backend static
balance roundrobin
server static 127.0.0.1:4331 check
#---------------------------------------------------------------------
# round robin balancing between the various backends
#---------------------------------------------------------------------
backend app
balance roundrobin
server app1 127.0.0.1:5001 check
server app2 127.0.0.1:5002 check
server app3 127.0.0.1:5003 check
server app4 127.0.0.1:5004 check
启动与关闭
- 启动
service haproxy start
- 关闭
service haproxy stop
- 重启
service haproxy restart
- 启动
使用
- 由于负载均衡服务器是 linux123,端口设置为25003,因此 可以通过 impala-shell 访问
impala-shell -i linux123:25003
- 如果是在 linux121中访问,则
- 访问前:
[linux121:21000] >
- 访问后:
[linux123:25003] >
- 访问前:
- 由于负载均衡服务器是 linux123,端口设置为25003,因此 可以通过 impala-shell 访问
2、Impala 优化
cloudera官网上的Impala文档,原名为《Impala Performance Guidelines and Best Practices》。主要介绍了为了提升impala性能应该考虑的一些事情,结合实际考虑:
基本优化策略
- 文件格式
- 对于大数据量来说,
Parquet
文件格式是最佳的
- 对于大数据量来说,
- 避免小文件
insert ... values
会产生大量小文件,避免使用
- 合理分区粒度
- 利用分区可以在查询的时候忽略掉无用数据,提高查询效率,通常建议分区数量在3万以下
- (太多的分区也会造成元数据管理的性能下降)
- 获取表的统计指标
- 在追求性能或者大数据量查询的时候,要先获取所需要的表的统计指标
- (如:执行
compute stats
)
- 减少传输客户端数据量
- 聚合(如 count、sum、max 等)
- 过滤(如WHERE )
- limit 限制返回条数
- 返回结果不要使用美化格式进行展示
- (在通过 impala-shell 展示结果时,添加这些可选参数:
-B
、--output_delimiter
)
- (在通过 impala-shell 展示结果时,添加这些可选参数:
- 在执行之前使用
EXPLAIN
来查看逻辑规划,分析执行逻辑,执行后可以用profile
进行分析 Impala join
自动的优化手段就是通过使用COMPUTE STATS
来收集参与Join的每张表的统计信息,然后由Impala根据表的大小、列的唯一值数目等来自动优化查询。为了更加精确地获取每张表的统计信息,每次表的数据变更时(如执行Insert,add partition,drop partition等)最好都要执行一遍COMPUTE STATS获取到准确的表统计信息。