Impala学习--Impala概述,Impala系统架构
Imapla概述
Impala是Cloudera公司的一个实时海量查询产品。是对于已有Hive产品的补充。Impala采用了和Hive相同的类SQL接口,但并没有采用MapRed框架执行任务,而是采用了类似Dremel的方式。号称秒级可以扫描PB数据。
其实Impala就是自己实现了一个执行引擎。这个引擎不像MapRed一样是一个通用框架,并且也没有任何failover和high availability的设计。但是优势在于执行速度足够快,秒级返回。其设计理念就是,执行速度足够快,快到如果失败了,重新执行一遍的代价也不大。
很显然,MapRed之所以流行就在于其可以很好的做到可扩展和容错。容错的价值在于,当一个大任务需要1小时以上的执行时间,如果在执行过程中发生故障,可以快速恢复,而不许要重新执行。所以这也是MPI任务为什么采用checkpoint的进行容错。都是为了减少机器故障给执行时间带来额开销。
Hive是在MapRed模型之上抽象出来的类似SQL的接口,简化了写MapRed程序的代价。同样由于依赖于MapRed系统,导致Hive任务执行时间很长,和MapRed一样,只适合执行批处理任务。
而面对实时查询的需求,旧的做法通常是先通过MapRed对数据进行加工,再导出到mysql等系统中。然而这种做法存在多个问题:
- 数据存在多个地方,如果管理不善,很容易带来数据不一致等各种问题
- 用户需要了解数据是否已存储在mysql中
- mysql对存储数据量有限制
其实用户的实时查询请求经常会扫描大量数据,但计算都相对简单,例如只是count(*),等等。为满足这种需求,Google提出了Dremel,而Cloudera参考了Dremel的设计思路,实现了Impala。
Impala存在以下特点:
- 面向实时查询,结果秒级返回
- 兼容hive的类sql语法,但暂时不支持udf和transform
- 可以和hive共享metastore
- 没有任何failover的设计
- 支持从hdfs和hbase读取数据
- 运行时环境用c++实现,并利用了llvm的技术,动态优化执行代码
最后说一下,Impala不会完全替代Hive,因为毕竟Hive的容错和稳定性是Impala比不了的。Impala只是Hive的一个补充,可以快速的响应一些简单的查询请求。
从业务角度上分析,如果Imapla能够做到在5秒,甚至更短的时间内返回结果,那将有机会替代现有的mysql或oracal数据库,成为决策系统的底层支撑查询引擎。例如目前Oracal的BI或类似的系统,底层使用的是传统关系数据库,对海量数据的查询性能非常差。如果替换成Impala,则能够访问的数据量将大的多,对BI系统在公司业务上的贡献将有质的飞跃。
预告一下,后续将继续发表一些和impala有关的文章,将会涉及到系统架构,如何安装调试,前端代码分析,后台代码分析,llvm优化等等。
Impala系统架构
上图中,黄色部分谓Imapla模块,蓝色部分为运行Impala依赖的其他模块。
从部署上看,Impala整体分为两部分:
- StateStore
- Impalad
其中StateStore是一个集群状态服务进程。在集群中只存在一个实例。Impalad是分布式的存在于集群中的worker进程。每一个Impalad又包含了以下部分:
- StateStoreSubscriber:订阅StateStore状态
- Scheduler:调度器
- Analyzer:对提交的Query进行语法分析
- Planner:生成执行计划
- Coordinator:管理一个Query的执行,包括分发给其他Impalad执行
- PlanFragmentExecutor:执行一个PlanFragment
同时,Impala依赖的外部系统包括:
- HDFS/HBase:用于读取查询数据
- HDFS NameNode:用于检查输入数据位置
- Hive MetaStore:用于访问表的元数据
整体流程:
- 客户端向某一个Impalad提交一个query
- Impalad通过jni,将query传送给java前端,由java前端完成语法分析和生成执行计划,并将执行计划封装成thrift格式返回执行计划分为多个阶段,每一个阶段叫做一个PlanFragment,每一个PlanFragment在执行时可以由多个Impalad实例并行执行(有些PlanFragment只能由一个Impalad实例执行)
- Coordinator根据执行计划,访问Scheduler,完成调度,并将任务分发给远端的Impalad执行
- 用户调用GetNext()方法获取计算结果,如果是insert语句,则将计算结果写回hdfs
- 当所有输入数据被消耗光,执行结束。
- 在执行过程中,如果有任何故障发生,则整个执行失败
这个流程与Hive相比,编译和生成执行计划阶段比较相似,但是执行阶段有很大不同:
- 执行计划
Hive依赖于MapRed执行框架,执行计划被严格划分成Map->Shuffle->Red->Map->Shuffle->Red…的模型。如果一个Qurey会被编译成多轮MapRed,则每一轮结束都会存在一个barrier。此外,如果Hive中有两个可以并行的子查询,且分组的key不相同,则需要两个独立的MapRed任务才能完成。这个问题在Impala中不存在。
Impala的执行计划是一刻完整的树(DAG),不受任何约束,这个执行计划和Dryad的DAG模型很相像。这个执行计划中,只有在必要的时候才会出现barrier,例如group,top等。其他的计算都是流式的。前面算子的计算结果,可以立即被后面算子消耗。
- 数据流
Hive的数据流采用推的方式,每一各计算节点计算完成后将数据主动下推给后续节点。
Impala采用拖的方式,后续节点主动向前面节点要数据。拖的方式的特点在于,数据可以流式的返回给客户端,只要有1条数据被处理完成,就可以立即展现出来。
- 外存使用
Hive执行过程中,如果内存放不下所有数据,则会利用外存,以保证query能顺利执行完。每一轮MapRed结束,中间结果也会写入hdfs中。由于Hadoop框架的限制,shuffle过程也会有写本地磁盘的操作。
Impala在遇到内存放不下数据时,则直接返回错误,而不会利用外存。这使得Impala目前能处理的Query可能收到一定的限制。例如在做聚合操作,或join时,可能因为内存不够而失败。同时Impala在多个阶段之间利用网络传输数据。总的来说,Impala执行过程中,不会有任何写磁盘操作(除非用户制定insert命令)
- 调度
Hive任务的调度依赖于Hadoop的调度策略。
Impala的调度由自己完成,目前的调度算法会尽量满足数据的局部性,即扫描数据的进程应尽量靠近数据本身所在的物理机器。但目前调度暂时还没有考虑负载均衡的问题。从Cloudera的资料看,Impala程序的瓶颈是网络IO,目前Impala中已经存在对Impalad机器网络吞吐进行统计,但目前还没有利用统计结果进行调度。
- 容错
Hive任务依赖于Hadoop框架的容错能力,可以做到很好的failover。
Impala中不存在任何容错逻辑,如果执行过程中发生故障,则直接返回错误。当一个Impalad失败时,在这个Impalad上正在运行的所有query都将失败。但由于Impalad是对等的,用户可以向其他Impalad提交query,不影响服务。当StateStore失败时,也不会影响服务,但由于Impalad已经不能再更新集群状态,如果此时有其他Impalad失败,则无法及时发现。这样调度时,如果谓一个已经失效的Impalad调度了一个任务,则整个query无法执行。
如果你喜欢本文, 请长按二维码,关注公众号 分布式编程.
作者:分布式编程
出处:https://zthinker.com/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。