# 简介
Impala 是一个分布式,大规模并行处理数据库引擎。
- 支持 SQL 实时查询
- 由 Java 和 C++ 实现
- 共享 Hive Metastore
- 支持多种数据存储格式,如 Text、Parquet、Avro 等
- 支持多种数据存储引擎,如 HDFS、KUDU、S3 等
- 能够与 Hadoop 集成
- ...
# Impala 架构
- impalad,部署在集群中的各个节点中,负责接受来自客户端进程的查询,并协调其在整个集群中的执行,以及执行其他 impalad 分配的单个查询片段。
- Query Planner,负责解析客户端的 SQL 生成一个执行计划树 。
- Query Coordinator,负责给其他 impalad 节点分发执行任务。
- Query Exec Engine,负责执行被分配的查询片段。
- statestored,部署在集群中的单个节点中,是 impala 的元数据发布订阅服务,负责将集群范围的元数据传播到所有 Impalad,同时收集集群中 impalad 的健康状况。
- catalogd,部署在集群中的单个节点中,充当 Impala 的目录存储库和元数据访问网关。
- cli,包括 Impala-shell、Hue 界面和 ODBC / JDBC 驱动程序。
# SQL 执行流程
- Client 向集群中的一个 impalad 发送 SQL 语句;
- Query Planner 解析这个 SQL 语句生成执行计划树;
- Query Coordinator 根据执行计划树向所有的 impalad 发送执行任务;
- Query Executor 执行被分配的查询片段;
- 查询结果返回给 Query Coordinator;
- 最后由 Query Coordinator 将结果汇总给 Client。
# 源码流程
# 生成并发送查询计划
——ImpalaServer::ExecuteStatement impala-hs2-server.cc
——ImpalaServer::Execute impala-server.cc
——ImpalaServer::ExecuteInternal impala-server.cc
——QueryDriver::RunFrontendPlanner query-driver.cc
——Frontend::GetExecRequest frontend.cc
——JniUtil::CallJniMethod jni-util.h
——JniFrontend::createExecRequest JniFrontend.java
——Frontend::createExecRequest Frontend.java
——Frontend::getTExecRequest Frontend.java
——Frontend::doCreateExecRequest Frontend.java
——Parser::parse Parser.java
——AnalysisContext::analyzeAndAuthorize AnalysisContext.java
——AnalysisContext::getPlannedExecRequest AnalysisContext.java
——Frontend::createExecRequest Frontend.java
——Planner::createPlans Planner.java
——SingleNodePlanner::createSingleNodePlan SingleNodePlanner.java
——DistributedPlanner::createPlanFragments DistributedPlanner.java
——Planner::computeResourceReqs Planner.java
——ClientRequestState::Exec client-request-state.cc
——ClientRequestState::ExecAsyncQueryOrDmlRequest client-request-state.cc
——ClientRequestState::FinishExecQueryOrDmlRequest client-request-state.cc
——RemoteAdmissionControlClient::SubmitForAdmission remote-admission-control-client.cc
——Coordinator::Exec coordinator.cc
——Coordinator::StartBackendExec coordinator.cc
——Coordinator::BackendState::ExecAsync coordinator-backend-state.cc
——ControlServiceProxy::ExecQueryFInstancesAsync control_service.proto
# 执行查询计划
——ControlService::ExecQueryFInstances control-service.cc
——QueryExecMgr::StartQuery query-exec-mgr.cc
——QueryExecMgr::ExecuteQueryHelper query-exec-mgr.cc
——QueryState::StartFInstances query-state.cc
——QueryState::ExecFInstance query-state.cc
——FragmentInstanceState::Exec fragment-instance-state.cc
——FragmentInstanceState::Prepare fragment-instance-state.cc
——ExecNode::CreateTree exec-node.cc
——ExecNode::Prepare() exec-node.cc
——FragmentInstanceState::Open fragment-instance-state.cc
——ExecNode::Open() exec-node.cc
——FragmentInstanceState::ExecInternal fragment-instance-state.cc
——ExecNode::GetNext() exec-node.cc
——FragmentInstanceState::Close fragment-instance-state.cc
——ExecNode::Close() exec-node.cc
# 查询计划
查询计划分为两阶段:
- 单机查询计划
- 分布式查询计划,尽量降级数据移动
# 例子
# sql
select | |
* | |
from | |
test_1 | |
join test_2 on test_1.id = test_2.id | |
order by | |
test_1.name_1 |
# 查询计划
# 查询优化
# 多表连接查询
连接方式有两种:
- broadcast,右表比左表小,右表会被发送到所有节点上
- partitioned,左右表大小差不多,两表都会有一部分数据被发送到其他节点上
连接方式的选择依赖于 compute stats 搜集的表的统计信息,straight_join 可以手动指定连接方式。
# 表统计信息
# compute stats
自动对表、分区及列进行信息统计。
# show table stats
表统计信息。
# show column stats
列统计信息。
# explain
输出查询执行的逻辑步骤。
# profile
输出最近执行的查询的详细信息。
# 代码结构
最主要关注 fe 和 be 部分。
# fe
├── cup 语法解析
├── java
│ └── org
│ └── apache
│ └── impala
│ ├── analysis,语义分析,例如检查表是否存在,列是否存在
│ ├── authentication,认证鉴权相关
│ ├── authorization,授权相关,例如 ranger、column、masking
│ ├── catalog,包含元数据操作的主类和各种数据库、表、分区的元数据实例类
│ ├── common,一些通用类,如 exception 相关
│ ├── compat
│ ├── extdatasource
│ ├── hive
│ ├── hooks
│ ├── planner,PlanNode、执行计划相关代码
│ ├── rewrite,表达式级别的改写优化,主要包括常量折叠、通用表达式提取、Between and 改下等
│ ├── service
│ └── util,一些工具类
└── jflex 词法解析
# be
├── benchmarks
├── catalog,元数据服务相关代码,与 statestore 交互,实现了 Thrift service
├── codegen,LLVM IR generation
├── common
├── exec,PlanNode 实现
├── experiments
├── exprs,Math、Date、String、Agg 等函数实现
├── gutil,google gutil 相关
├── kudu,引用的 kudu 的相关代码,例如 krpc
├── rpc,Rpc 协议相关代码
├── runtime,Coordinator 及查询运行时相关代码
├── scheduling,Admission control、调度相关
├── service,BE 对外服务接口相关代码,主函数 daemon-main 位于这个目录下
├── statestore,Statestore 相关
├── testutil
├── thirdparty,第三方依赖库
├── transport
├── udf,用户自定义函数相关代码
├── udf_samples
└── util,工具类相关
# 相关资料
- official website: https://impala.apache.org/
- repo: https://github.com/apache/impala
- wiki: https://cwiki.apache.org/confluence/display/IMPALA/Impala+Home
- doc: https://impala.apache.org/docs/build/html/topics/impala_intro.html
- cloudera doc: https://docs.cloudera.com/documentation/enterprise/6/6.3/topics/impala.html