主要内容

第 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的优化)

第 1 部分 Impala概述

1.1 Impala是什么

Impala是Cloudera提供的一款开源的针对HDFS和HBASE中的PB级别数据进行交互式实时查询(Impala速度快),Impala是参照谷歌的新三篇论文当中的Dremel实现而来,其中旧三篇论文分别是(BigTable,GFS,MapReduce)分别对应我们即将学的HBase和已经学过的HDFS以及MapReduce。
Impala最大卖点和最大特点就是快速,Impala中文翻译是高角羚羊。

1.2 Impala优势

Impala的诞生

之前学习的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启动时间。
  • 使用LLVM(C++编写的编译器)产生运行代码,针对特定查询生成特定代码。
  • 优秀的IO调度,Impala支持直接数据块读取和本地代码计算。
  • 选择适合的数据存储格式可以得到最好的性能(Impala支持多种存储格式)。
  • 尽可能使用内存,中间结果不写磁盘,及时通过网络以stream的方式传递。

Impala与Hive对比分析
查询过程

  • Hive:在Hive中,每个查询都有一个“冷启动”的常见问题。(map,reduce每次都要启动关闭,申请资源,释放资源。。。)
  • Impala:Impala避免了任何可能的启动开销,这是一种本地查询语言。 因为要始终处理查询,则Impala守护程序进程总是在集群启动之后就准备就绪。守护进程在集群启动之后可以接收查询任务并执行查询任务。

中间结果

  • Hive:Hive通过MR引擎实现所有中间结果,中间结果需要落盘,这对降低数据处理速度有不利影响。
  • Impala:在执行程序之间使用流的方式传输中间结果,避免数据落盘。尽可能使用内存避免磁盘开销

交互查询

  • Hive:对于交互式计算,Hive不是理想的选择。
  • Impala:对于交互式计算,Impala非常适合。(数据量级PB级)

计算引擎

  • Hive:是基于批处理的Hadoop MapReduce
  • Impala:更像是MPP数据库

容错

  • Hive:Hive是容错的(通过MR&Yarn实现)
  • Impala:Impala没有容错,由于良好的查询性能,Impala遇到错误会重新执行一次查询

查询速度

  • Impala:Impala比Hive快3-90倍。

Impala**优势总结**

  1. Impala最大优点就是查询速度快,在一定数据量下;
  2. 速度快的原因:避免了MR引擎的弊端,采用了MPP数据库技术,

1.3 Impala的缺点

  1. Impala属于MPP架构,只能做到百节点级,一般并发查询个数达到20左右时,整个系统的吞吐已经达到满负荷状态,在扩容节点也提升不了吞吐量,处理数据量在PB级别最佳。
  2. 资源不能通过YARN统一资源管理调度,所以Hadoop集群无法实现Impala、Spark、Hive等组件的动态资源共享。

1.4 适用场景

Hive:
复杂的批处理查询任务,数据转换任务,对实时性要求不高同时数据量又很大的场景。
Impala
实时数据分析,与Hive配合使用,对Hive的结果数据集进行实时分析。impala不能完全取代hive,impala可以直接处理hive表中的数据。

第 2 部分 Impala 安装与入门案例

2.1 集群准备

2.1.1 安装Hadoop,Hive

Impala的安装需要提前装好Hadoop,Hive这两个框架,
hive需要在所有的Impala安装的节点上面都要有,因为Impala需要引用Hive的依赖包,
hadoop的框架需要支持C程序访问接口,查看下图,如果有该路径有.so结尾文件,就证明支持C接口。
image.png
image.png

2.1.2 准备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命令默认源
image.png

本地**Yum**源方式
image.png
具体制作步骤
Yum源是Centos当中下载软件rpm包的地址,因此通过制作本地Yum源并指定Yum命令使用本地Yum源,为了使Yum命令(本机,跨网络节点)可以通过网络访问到本地源,我们使用Httpd这种静态资源服务器来开放我们下载所有的rpm包。
1. Linux121安装Httpd服务器

  1. #yum方式安装httpd服务器
  2. yum install httpd -y
  3. #启动httpd服务器
  4. systemctl start httpd
  5. #验证httpd工作是否正常,默认端口是80,可以省略
  6. http://linux121

image.png
2. 新建一个测试页面
httpd默认存放页面路径

/var/www/html/

新建一个页面test.html

<html> 
  <div style="font-size:100px"> this is a new page!! </div>
</html>

访问

http://linux121/test.html

注:后续可以把下载的**rpm**包解压放置到此处便可以供大家访问。

  1. 下载Impala安装所需rpm包
    Impala所需安装包需要到Cloudera提供地址下载
    http://archive.cloudera.com/cdh5/repo-as-tarball/5.7.6/cdh5.7.6-centos7.tar.gz
    
    注意:该tar.gz包是包含了Cloudera所提供的几乎所有rpm包,但是为了方便我们不再去梳理其中依赖关系,全部下载来,整个文件比较大,有3.8G。选择一个磁盘空间够的节点,后续还要把压缩包解压所以磁盘空间要剩余10G以上。
    image.png
    移动该安装包到/opt/software
    解压缩
    tar -zxvf cdh5.7.6-centos7.tar.gz
    
  2. 使用Httpd盛放依赖包
    创建软链接到/var/www/html下
    ln -s /opt/software/cdh/5.7.6 /var/www/html/cdh57
    
    验证
    http://linux121/cdh57/
    
    image.png
    如果提示403 forbidden
    vim /etc/selinux/config
    
    将SELINUX=enforcing改为SELINUX=disabled
    image.png
    修改之后要记得重启机器!!之前修改过可以不用修改!!
    5. 修改Yum源配置文件
    cd /etc/yum.repos.d 
    #创建一个新的配置文件
    vim local.repo
    #添加如下内容
    [local]
    name=local
    baseurl=http://linux121/cdh57/
    gpgcheck=0
    enabled=1
    
  • name:对于当前源的描述
  • baseurl:访问当前源的地址信息
  • gpgcheck: 1 0,gpg校验
  • enabled:1/0,是否使用当前源
  1. 分发local.repo文件到其它节点
    rsync-script local.repo
    

    2.2 安装Impala

    2.2.1 集群规划

    | 服务名称 | linux121 | linux122 | linux123 | | —- | —- | —- | —- | | impala-catalogd | 不安装 | 不安装 | 安装 | | impala-statestored | 不安装 | 不安装 | 安装 | | impala-server | 安装 | 安装 | 安装 |

Impala角色

  • impala-server:这个进程是Impala真正工作的进程,官方建议把impala-server安装在datanode节点,更靠近数据(短路读取),进程名impalad
  • impala-statestored:健康监控角色,主要监控impala-server,impala-server出现异常时告知给其它
  • impala-server;进程名叫做statestored
  • impala-catalogd :管理和维护元数据(Hive),impala更新操作;把impala-server更新的元数据通知给其它impala-server,进程名catalogd

官方建议statestorecatalog安装在同一节点上!!

2.2.2 具体安装步骤

Linux123

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

Linux121与Linux122

yum install impala-server -y
yum install impala-shell -y

配置**Impala**

  1. 修改hive-site.xml ```xml vim hive-site.xml
hive.metastore.uris thrift://linux121:9083,thrift://linux123:9083 hive.metastore.client.socket.timeout 3600 2. 分发Hive安装包到集群节点shell rsync -r /opt/servers/hive-2.3.7/ linux122:/opt/servers/ rsync -r /opt/servers/hive-2.3.7/ linux121:/opt/servers/ 3. Linux123启动metastore服务shell nohup hive —service metastore & 启动hiveserver2服务shell nohup hive —service hiveserver2 & 4. 修改HDFS集群hdfs-site.xml 配置HDFS集群的短路读取 <a name="iA6Lb"></a> #### 什么是短路读取? 在HDFS中通过DataNode来读取数据。但是,当客户端向DataNode请求读取文件时,DataNode就会从磁盘读取该文件并通过TCP socket将数据发送到客户端。所谓“短路”是指Client客户端直接读取文件。很明显,这种情况只在客户端与数据放在同一地点(译者注:同一主机)时才有可能发生。短路读对于许多应用程序会带来重大的性能提升。<br />短路读取:就是Client与DataNode属于同一节点,无需再经过网络传输数据,直接本地读取。要配置短路本地读,需要验证本机Hadoop是否有libhadoop.so; 进入一下目录:shell /opt/servers/hadoop-2.9.2/lib/native ![image.png](https://cdn.nlark.com/yuque/0/2021/png/12561076/1613963990574-9bad90d2-6793-40c1-9298-7cb98c96440b.png#align=left&display=inline&height=135&margin=%5Bobject%20Object%5D&name=image.png&originHeight=153&originWidth=819&size=110987&status=done&style=none&width=724) <a name="CVpoU"></a> #### 短路读取配置步骤 1. 创建短路读取本地中转站shell #所有节点创建一下目录 mkdir -p /var/lib/hadoop-hdfs 2. 修改hdfs-site.xmlxml dfs.client.read.shortcircuit true dfs.domain.socket.path /var/lib/hadoop-hdfs/dn_socket

dfs.datanode.hdfs-blocks-metadata.enabled true

dfs.client.file-block-storage-locations.timeout 30000

注:分发到集群其它节点。重启Hadoop集群。
```shell
#停止集群
stop-dfs.sh
stop-yarn.sh

#启动集群
start-dfs.sh
start-yarn.sh
  1. Impala具体配置

引用**HDFSHive**配置
**
使用Yum方式安装impala默认的Impala配置文件目录为 /etc/impala/conf,Impala的使用要依赖Hadoop,Hive框架,所以需要把Hdfs,Hive的配置文件告知Impala。执行以下命令把Hdfs,Hive的配置文件软链接到/etc/impala/conf下

ln -s /opt/servers/hadoop-2.9.2/etc/hadoop/core-site.xml /etc/impala/conf/core-site.xml
ln -s /opt/servers/hadoop-2.9.2/etc/hadoop/hdfs-site.xml /etc/impala/conf/hdfs-site.xml
ln -s /opt/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=linux123
IMPALA_STATE_STORE_HOST=linux123

所有节点创建mysql的驱动包的软链接

#创建节点 
mkdir -p /usr/share/java
ln -s /opt/servers/hive-2.3.7/lib/mysql-connector-java-5.1.46.jar
 /usr/share/java/mysql-connector-java.jar

image.png
修改**bigtopjava_home**路径

vim /etc/default/bigtop-utils
export JAVA_HOME=/opt/servers/jdk1.8.0_231

image.png
注意:Apache Bigtop 是一个针对基础设施工程师和数据科学家的开源项目,旨在全面打包、测试和配置领先的开源大数据组件/项目。Impala项目中使用到了此软件。

启动Impala

#linux123启动如下角色
service impala-state-store start
service impala-catalog start
service impala-server start

#其余节点启动如下角色
service impala-server start

验证Impala启动结果

ps -ef | grep impala

[root@linux123 conf]# ps -ef | grep impala
impala 29212 1 1 23:42 ? 00:00:00 /usr/lib/impala/sbin/statestored
-log_dir=/var/log/impala - state_store_port=24000
impala 29249 1 21 23:42 ? 00:00:04 /usr/lib/impala/sbin/catalogd
-log_dir=/var/log/impala
impala 29341 1 30 23:42 ? 00:00:06 /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

[root@linux122 conf]# ps -ef | grep impala
impala 25233 1 41 23:43 ? 00:00:04 /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

[root@linux121 conf]# ps -ef | grep impala
impala 21992 1 59 23:43 ? 00:00:04 /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

浏览器Web界面验证

访问impalad的管理界面 
http://linux123:25000/

访问statestored的管理界面
http://linux123:25010/

Impalad管理界面
image.png

Statestore管理界面
image.png
注意:启动之后所有关于Impala的日志默认都在/var/log/impala 这个路径下,Linux123机器上面应该有三个进程,Linux121与Linux122机器上面只有一个进程,如果进程个数不对,去对应目录下查看报错日志.

消除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

jps 时出现没有名字的进程 或者process information unavailable
image.png

解决方式

rm -rf /tmp/hsperfdata_impala

2.3 Impala入门案例

使用Yum方式安装Impala后,impala-shell可以全局使用;进入impala-shell命令行
impala-shell进入到impala的交互窗口

[root@linux123 conf]# impala-shell
Connected to linux123:21000
Server version: impalad version 2.3.0-cdh5.5.0 RELEASE (build
0c891d79aa38f297d244855a32f1e17280e2129b)
***********************************************************************************
Welcome to the Impala shell. Copyright (c) 2015 Cloudera, Inc. All rights reserved. 
(Impala Shell v2.3.0-cdh5.5.0 (0c891d7) built on Mon Nov 9 12:18:12 PST 2015)

The SET command shows the current value of all shell and query options.
***********************************************************************************
[linux123:21000] >

查看所有数据库

show databases;

Fetched 0 row(s) in 4.74s
[linux123:21000] > show databases;
Query: show databases
+------------------+
| name                         |
+------------------+
| _impala_builtins |
| default                     |
|                                     |
+------------------+

如果想要使用Impala ,需要将数据加载到Impala中,如何加载数据到Impala中呢?

  • 使用Impala的外部表,这种适用于已经有数据文件,只需将数据文件拷贝到HDFS上,创建一张Impala外部表,将外部表的存储位置指向数据文件的位置即可。(类似Hive)
  • 通过Insert方式插入数据,适用于我们没有数据文件的场景。


  1. 准备数据文件

user.csv

392456197008193000,张三,20,0
267456198006210000,李四,25,1
892456199007203000,王五,24,1
492456198712198000,赵六,26,2
392456197008193000,张三,20,0
392456197008193000,张三,20,0
  1. 创建HDFS 存放数据的路径

    hadoop fs -mkdir -p /user/impala/t1
    #上传本地user.csv到hdfs /user/impala/table1
    hadoop fs -put user.csv /user/impala/t1
    
  2. 创建表 ```sql

    进入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’;


4.  查询数据
```sql
 select * from t1;

image.png

  1. 创建t2表 ```sql

    创建一个内部表

    create table t2( id string, name string, age int, gender int ) row format delimited fields terminated by ‘,’;

查看表结构

desc t1; desc formatted t2;


6.  插入数据到t2
```sql
insert overwrite table t2 select * from t1 where gender =0;
#验证数据
select * from t2;

image.png

更新元数据

使用Beeline连接Hive查看Hive中的数据,发现通过Impala创建的表,导入的数据都可以被Hive感知到。

0: jdbc:hive2://linux123:10000> show tables;

image.png

0: jdbc:hive2://linux123:10000> select * from t1;

image.png

小结:

  1. 上面案例中Impala的数据文件我们准备的是以逗号分隔的文本文件,实际上,Impala可以支持RCFile,SequenceFile,Parquet等多种文件格式。
  2. Impala与Hive元数据的关系?

Hive对于元数据的更新操作不能被Impala感知到;
Impala对元数据的更新操作可以被Hive感知到。

Impala同步Hive元数据命令:
手动执行invalidate metadata ,(后续详细讲解)

Impala是通过Hive的metastore服务来访问和操作Hive的元数据,但是Hive对表进行创建删除修改等操作,Impala是无法自动识别到Hive中元数据的变更情况的,如果想让Impala识别到Hive元数据的变化,所以需要进入impala-shell之后首先要做的操作就是执行invalidatemetadata,该命令会将所有的Impala的元数据失效并重新从元数据库同步元数据信息。后面详细讲解元数据更新命令。

  1. Impala操作HDFS使用的是Impala用户,所以为了避免权限问题,我们可以选择关闭权限校验

在hdfs-site.xml中添加如下配置:

<!--关闭hdfs权限校验 -->
<property>
  <name>dfs.permissions.enabled</name>
  <value>false</value>
</property>

第 3 部分 Imapla的架构原理

第 1 节 Impala的组件

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

image.png

image.png

impalad

  • 角色名称为Impala Daemon,是在每个节点上运行的进程,是Impala的核心组件,进程名是Impalad;
  • 作用,负责读写数据文件,接收来自Impala-shell,JDBC,ODBC等的查询请求,与集群其它Impalad分布式并行完成查询任务,并将查询结果返回给中心协调者。
  • 为了保证Impalad进程了解其它Impalad的健康状况,Impalad进程会一直与statestore保持通信。
  • Impalad服务由三个模块组成:Query Planner、Query Coordinator和Query Executor,前两个模块组成前端,负责接收SQL查询请求,解析SQL并转换成执行计划,交由后端执行,

statestored

  • statestore监控集群中Impalad的健康状况,并将集群健康信息同步给Impalad,
  • statestore进程名为statestored

catalogd

  • Impala执行的SQL语句引发元数据发生变化时,catalog服务负责把这些元数据的变化同步给其它Impalad进程(日志验证,监控statestore进程日志)
  • catalog服务对应进程名称是catalogd
  • 由于一个集群需要一个catalogd以及一个statestored进程,而且catalogd进程所有请求都是经过statestored进程发送,所以官方建议让statestored进程与catalogd进程安排同个节点。

第 2 节 Impala的查询

image.png

  1. Client提交任务

Client发送一个SQL查询请求到任意一个Impalad节点,会返回一个queryId用于之后的客户端操作。

  1. 生成单机和分布式执行计划

SQL提交到Impalad节点之后,Analyser依次执行SQL的词法分析、语法分析、语义分析等操作;从MySQL元数据库中获取元数据,从HDFS的名称节点中获取数据地址,以得到存储这个查询相关数据的所有数据节点

  • 单机执行计划: 根据上一步对SQL语句的分析,由Planner先生成单机的执行计划,该执行计划是有PlanNode组成的一棵树,这个过程中也会执行一些SQL优化,例如Join顺序改变、谓词下推等。
  • 分布式并行物理计划:将单机执行计划转换成分布式并行物理执行计划,物理执行计划由一个个的Fragment组成,Fragment之间有数据依赖关系,处理过程中需要在原有的执行计划之上加入一些ExchangeNode和DataStreamSink信息等。
    • Fragment : sql生成的分布式执行计划的一个子任务;
    • DataStreamSink:传输当前的Fragment输出数据到不同的节点
      1. 任务调度和分发

Coordinator将Fragment(子任务)根据数据分区信息发配到不同的Impalad节点上执行。Impalad节点接收到执行Fragment请求交由Executor执行。

  1. Fragment之间的数据依赖

    每一个Fragment的执行输出通过DataStreamSink发送到下一个Fragment,Fragment运行过程中不断向coordinator节点汇报当前运行状态。

  2. 结果汇总

查询的SQL通常情况下需要有一个单独的Fragment用于结果的汇总,它只在Coordinator节点运行,将多个节点的最终执行结果汇总,转换成ResultSet信息。

  1. 获取结果

客户端调用获取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生成单机的执行计划

image.png
分析上面的单机执行计划,第一步先去扫描t1表中需要的数据,如果数据文件存储是列式存储我们可以便利的扫描到所需的列id,n1;接着需要与t2表进行Join操作,扫描t2表与t1表类似获取到所需数据列id,n2;t1与t2表进行关联,关联之后再与t3表进行关联,这里Impala会使用谓词下推扫描t3表只取joi所需数据;对group by进行相应的aggregation操作,最终是排序取出指定数量的数据返回。

分布式并行执行计划

所谓的分布式并行化执行计划就是在单机执行计划基础之上结合数据分布式存储的特点,按照任务的计算要求把单机执行计划拆分为多段子任务,每个子任务都是可以并行执行的。上面的单机执行计划转为分布式并行执行计划如下图所示:
image.png

分布式并行执行计划流程图
image.png
分布式执行计划中涉及到多表的Join,Impala会根据表的大小来决定Join的方式,主要有两种分别是Hash Join与Broadcast Join
上面分布式执行计划中可以看出T1,T2表大一些,而T3表小一些,所以对于T1与T2的Join Impala选择使用Hash Join,对于T3表选择使用Broadcast 方式,直接把T3表广播到需要Join的节点上。

分布式并行计划流程

  1. T1和T2使用Hash join,此时需要按照id的值分别将T1和T2分散到不同的Impalad进程,但是相同的id会散列到相同的Impalad进程,这样每一个Join之后是全部数据的一部分
  2. T1与T2Join之后的结果数据再与T3表进行Join,此时T3表采用Broadcast方式把自己全部数据(id列)广播到需要的Impala节点上
  3. T1,T2,T3Join之后再根据Group by执行本地的预聚合,每一个节点的预聚合结果只是最终结果的一部分(不同的节点可能存在相同的group by的值),需要再进行一次全局的聚合。
  4. 全局的聚合同样需要并行,则根据聚合列进行Hash分散到不同的节点执行Merge运算(其实仍然是一次聚合运算),一般情况下为了较少数据的网络传输, Impala会选择之前本地聚合节点做全局聚合工作。
  5. 通过全局聚合之后,相同的key只存在于一个节点,然后对于每一个节点进行排序和TopN计算,最终将每一个全局聚合节点的结果返回给Coordinator进行合并、排序、limit计算,返回结果给用户.