1. impala架构 impala是cloudera在受到google的dremel启发下开发的实时交互sql大数据查询工具,impala没有再使用缓慢的hive+mapreduce批处理,而是通过使用与商用并行关系数据库中类似的分布式查询引擎(由query planner、query coordinator和query exec eng
1. impala架构impala是cloudera在受到google的dremel启发下开发的实时交互sql大数据查询工具,impala没有再使用缓慢的hive+mapreduce批处理,而是通过使用与商用并行关系数据库中类似的分布式查询引擎(由query planner、query coordinator和query exec engine三部分组成),可以直接从hdfs或hbase中用select、join和统计函数查询数据,从而大大降低了延迟。其架构如图 1所示,impala主要由impalad, state store和cli组成。
图 1
impalad: 与datanode运行在同一节点上,由impalad进程表示,它接收客户端的查询请求(接收查询请求的impalad为coordinator,coordinator通过jni调用java前端解释sql查询语句,生成查询计划树,再通过调度器把执行计划分发给具有相应数据的其它impalad进行执行),读写数据,并行执行查询,并把结果通过网络流式的传送回给coordinator,由coordinator返回给客户端。同时impalad也与state store保持连接,用于确定哪个impalad是健康和可以接受新的工作。在impalad中启动三个thriftserver: beeswax_server(连接客户端),hs2_server(借用hive元数据), be_server(impalad内部使用)和一个impalaserver服务。
impala state store: 跟踪集群中的impalad的健康状态及位置信息,由statestored进程表示,它通过创建多个线程来处理impalad的注册订阅和与各impalad保持心跳连接,各impalad都会缓存一份state store中的信息,当state store离线后(impalad发现state store处于离线时,会进入recovery模式,反复注册,当state store重新加入集群后,自动恢复正常,更新缓存数据)因为impalad有state store的缓存仍然可以工作,但会因为有些impalad失效了,而已缓存数据无法更新,导致把执行计划分配给了失效的impalad,导致查询失败。
cli: 提供给用户查询使用的命令行工具(impala shell使用python实现),同时impala还提供了hue,jdbc, odbc使用接口。
impala与hive都是构建在hadoop之上的数据查询工具各有不同的侧重适应面,但从客户端使用来看impala与hive有很多的共同之处,如数据表元数据、odbc/jdbc驱动、sql语法、灵活的文件格式、存储资源池等。impala与hive在hadoop中的关系如图 2所示。hive适合于长时间的批处理查询分析,而impala适合于实时交互式sql查询,impala给数据分析人员提供了快速实验、验证想法的大数据分析工具。可以先使用hive进行数据转换处理,之后使用impala在hive处理后的结果数据集上进行快速的数据分析。
图 2
3. impala的查询处理过程
impalad分为java前端与c++处理后端,接受客户端连接的impalad即作为这次查询的coordinator,coordinator通过jni调用java前端对用户的查询sql进行分析生成执行计划树,不同的操作对应不用的plannode, 如:selectnode, scannode, sortnode, aggregationnode, hashjoinnode等等。
执行计划树的每个原子操作由一个planfragment表示,通常一条查询语句由多个plan fragment组成, plan fragment 0表示执行树的根,汇聚结果返回给用户,执行树的叶子结点一般是scan操作,分布式并行执行。
java前端产生的执行计划树以thrift数据格式返回给impala c++后端(coordinator)(执行计划分为多个阶段,每一个阶段叫做一个planfragment,每一个planfragment在执行时可以由多个impalad实例并行执行(有些planfragment只能由一个impalad实例执行,如聚合操作),整个执行计划为一执行计划树),由coordinator根据执行计划,数据存储信息(impala通过libhdfs与hdfs进行交互。通过hdfsgethosts方法获得文件数据块所在节点的位置信息),通过调度器(现在只有simple-scheduler, 使用round-robin算法)coordinator::exec对生成的执行计划树分配给相应的后端执行器impalad执行(查询会使用llvm进行代码生成,编译,执行。对于使用llvm如何提高性能这里有说明),通过调用getnext()方法获取计算结果,如果是insert语句,则将计算结果通过libhdfs写回hdfs当所有输入数据被消耗光,执行结束,之后注销此次查询服务。
impala的查询处理流程大概如图3所示:
图 3
下面以一个sql查询语句为例分析impala的查询处理流程。如select sum(id), count(id), avg(id) from customer_small group by id; 以此语句生成的计划为:
plan fragment 0
partition: unpartitioned
4:exchange
tuple ids: 1
plan fragment 1
partition: hash_partitioned:
stream data sink
exchange id: 4
unpartitioned
3:aggregate
| output: sum(), sum()
| group by:
| tuple ids: 1
|
2:exchange
tuple ids: 1
plan fragment 2
partition: random
stream data sink
exchange id: 2
hash_partitioned:
1:aggregate
| output: sum(id), count(id)
| group by: id
| tuple ids: 1
|
0:scan hdfs
table=default.customer_small #partitions=1 size=193b
tuple ids: 0
执行行计划树如图 4所示, 绿色的部分为可以分布式并行执行:
图 4
1、没有使用mapreduce进行并行计算,虽然mapreduce是非常好的并行计算框架,但它更多的面向批处理模式,而不是面向交互式的sql执行。与mapreduce相比:impala把整个查询分成一执行计划树,而不是一连串的mapreduce任务,在分发执行计划后,impala使用拉式获取数据的方式获取结果,把结果数据组成按执行树流式传递汇集,减少的了把中间结果写入磁盘的步骤,再从磁盘读取数据的开销。impala使用服务的方式避免每次执行查询都需要启动的开销,即相比hive没了mapreduce启动时间。
2、使用llvm产生运行代码,针对特定查询生成特定代码,同时使用inline的方式减少函数调用的开销,加快执行效率。
3、充分利用可用的硬件指令(sse4.2)。
4、更好的io调度,impala知道数据块所在的磁盘位置能够更好的利用多磁盘的优势,同时impala支持直接数据块读取和本地代码计算checksum。
5、通过选择合适的数据存储格式可以得到最好的性能(impala支持多种存储格式)。
6、最大使用内存,中间结果不写磁盘,及时通过网络以stream的方式传递。
5. impala与hive的异同数据存储:使用相同的存储数据池都支持把数据存储于hdfs, hbase。
元数据:两者使用相同的元数据。
sql解释处理:比较相似都是通过词法分析生成执行计划。
执行计划:
hive: 依赖于mapreduce执行框架,执行计划分成map->shuffle->reduce->map->shuffle->reduce…的模型。如果一个query会被编译成多轮mapreduce,则会有更多的写中间结果。由于mapreduce执行框架本身的特点,过多的中间过程会增加整个query的执行时间。
impala: 把执行计划表现为一棵完整的执行计划树,可以更自然地分发执行计划到各个impalad执行查询,而不用像hive那样把它组合成管道型的map->reduce模式,以此保证impala有更好的并发性和避免不必要的中间sort与shuffle。
数据流:
hive: 采用推的方式,每一个计算节点计算完成后将数据主动推给后续节点。
impala: 采用拉的方式,后续节点通过getnext主动向前面节点要数据,以此方式数据可以流式的返回给客户端,且只要有1条数据被处理完,就可以立即展现出来,而不用等到全部处理完成,更符合sql交互式查询使用。
内存使用:
hive: 在执行过程中如果内存放不下所有数据,则会使用外存,以保证query能顺序执行完。每一轮mapreduce结束,中间结果也会写入hdfs中,同样由于mapreduce执行架构的特性,shuffle过程也会有写本地磁盘的操作。
impala: 在遇到内存放不下数据时,当前版本1.0.1是直接返回错误,而不会利用外存,以后版本应该会进行改进。这使用得impala目前处理query会受到一定的限制,最好还是与hive配合使用。impala在多个阶段之间利用网络传输数据,在执行过程不会有写磁盘的操作(insert除外)。
调度:
hive: 任务调度依赖于hadoop的调度策略。
impala: 调度由自己完成,目前只有一种调度器simple-schedule,它会尽量满足数据的局部性,扫描数据的进程尽量靠近数据本身所在的物理机器。调度器目前还比较简单,在simplescheduler::getbackend中可以看到,现在还没有考虑负载,网络io状况等因素进行调度。但目前impala已经有对执行过程的性能统计分析,应该以后版本会利用这些统计信息进行调度吧。
容错:
hive: 依赖于hadoop的容错能力。
impala: 在查询过程中,没有容错逻辑,如果在执行过程中发生故障,则直接返回错误(这与impala的设计有关,因为impala定位于实时查询,一次查询失败,再查一次就好了,再查一次的成本很低)。但从整体来看,impala是能很好的容错,所有的impalad是对等的结构,用户可以向任何一个impalad提交查询,如果一个impalad失效,其上正在运行的所有query都将失败,但用户可以重新提交查询由其它impalad代替执行,不会影响服务。对于state store目前只有一个,但当state store失效,也不会影响服务,每个impalad都缓存了state store的信息,只是不能再更新集群状态,有可能会把执行任务分配给已经失效的impalad执行,导致本次query失败。
适用面:
hive: 复杂的批处理查询任务,数据转换任务。
impala:实时数据分析,因为不支持udf,能处理的问题域有一定的限制,与hive配合使用,对hive的结果数据集进行实时分析。
优点:
缺点:
【说明】:本文章由站长整理发布,文章内容不代表本站观点,如文中有侵权行为,请与本站客服联系(QQ:)!