SQL on Hadoop 之查询效率分析

本文选择了一句比较有代表性的查询语句,分别用不同的执行引擎执行,hive on mr 用时278s,hive on tez用时44s,spark SQL 用时24s,而presto只要18s。本文详细分析在执行这段查询的过程中,每个执行引擎的效率差异是在哪个阶段体现出来的,又能体现多少程度,原因又是什么。

本文分析用的benchmark 是TPC-DS,查询语句如下:

select  i_item_desc
      ,i_category
      ,i_class
      ,i_current_price
      ,i_item_id
      ,sum(ws_ext_sales_price) as itemrevenue
      ,sum(ws_ext_sales_price)*100/sum(sum(ws_ext_sales_price)) over
          (partition by i_class) as revenueratio
from
        web_sales
        ,item
        ,date_dim
where
        web_sales.ws_item_sk = item.i_item_sk
        and item.i_category in ('Jewelry', 'Sports', 'Books')
        and web_sales.ws_sold_date_sk = date_dim.d_date_sk
        and date_dim.d_date between '2001-01-12' and '2001-02-11'
group by
        i_item_id
        ,i_item_desc
        ,i_category
        ,i_class
        ,i_current_price
order by
        i_category
        ,i_class
        ,i_item_id
        ,i_item_desc
        ,revenueratio
limit 100;

这段sql包含了两个inner join,有window function,aggregation,group by,order by。比较有代表性的一个查询。
其中表的数据量为:
web_sales: 716446671 rows, 48.1G
item: 300000 rows, 18.6M
date_dim: 73049 rows, 352.8 K

分析之前的几点声明:
1.执行效率的分析必须保证可用资源一致。这次评测通过yarn队列的资源限制保证hive和spark的最大可用资源一致。presto不基于yarn,只配置了单个查询最大可用内存小于hive和spark。
2.查询效率跟集群状态相关,这里取的是重复多次后的最快时间
3.各stage的时间是从log中获取的,从一个task执行完,到打印出log可能有延迟,所以时间可能有少量误差
4.很多配置项会影响执行过程,执行效率,这次分析使用的是我们集群当前的配置,并不保证所有的配置已经完全利用了各平台的特性
5.不同引擎对不同类型的查询优化程度不一样,要完整评测的话需要测试更多类型的查询

先看hive on mr ,hive on mr的执行流程为
1.SQL -> AST -> OPTree->执行计划
2.执行计划包含多个mr job,向MR框架依次提交执行
下图是执行计划中各个job执行所占的时间:


hive on mr 执行计划各阶段用时

hive on mr的执行时间是278s,其中有130s(各个stage间的时间)用在了job提交、资源分配和运行环境初始化。可见几乎一半的时间没有用在job执行上面。

来看hive on tez,hive on tez的执行流程为
1.SQL -> AST -> OPTree->执行计划
2.执行计划包含一个DAG,向tez提交DAG执行
下图为DAG执行时间


hive on tez 执行计划各阶段用时

hive on tez的执行时间是44s,DAG运行时间29s,编译sql生成执行计划用了3s。对比hive on mr,我们可以看出:
第一,hive on mr中的job提交、资源分配和运行环境初始化从130s减少到12s,因为hive on tez整个DAG是一个job,job提交只有一次,job内的container重用。
第二,job执行从126s减少到29s,这是因为tez灵活的DAG模型
1.使三个map的vertex可以并发执行
2.不再拘泥于map、reduce成对出现,可以有一串reduce
3.edge的channel可以是自定义的,不必非得是hdfs

再看spark sql,spark sql的执行流程为
1.SQL -> AST -> OPTree->RDD
2.遇到action生成job,生成一个job直接提交;job根据RDD transformation的宽依赖划分stage
job间可以并发执行,stage 顺序执行


spark SQL执行计划各阶段用时

spark 执行时间为24s
1.其job执行占了22.3s(job1和job2并行), 其container的重用已经做到了极致,所有资源都是一开始申请好的。
2.其对web_sales的读取并join(broad cast + job2 stage2)比tez(map1,reduce2,reduce3)快了9s,因为:
1)多了两个project的pushdown,见下图,在spark的执行计划中,在broadcast date_dim表的数据之前以及第二次broadcast join之间都进行了project,进行了column pruning;而在hive on tez的执行计划中,可见并没有相应的select operator。
2)spark 的broadcast 采用P2P方式,速度更快


spark SQL vs hive on tez

再看presto,presto不依赖yarn进行资源管理,presto集群分为coordinator和worker节点,SQL提交到coordinator
1.SQL -> AST -> OPTree -> execution plan -> subplans
2.每个subplan 提交到多个worker上执行,下图是presto上的执行计划
presto 执行计划

presto总执行时间17.7s。

presto相比spark SQL的速度更快的原因:
1.其模型有跨stage的流水线处理。其整个执行计划各部分会同时分发到各个worker,其中exchange operator会主动向上游worker节点拉取数据。也就是说上一个stage还没处理完,只要已经有数据产出,下一个stage就已经开始执行了。所以上图中没有指出各stage的执行时间,因为没有比较意义。
2.见下图,presto的每个表扫描之后都进行了projection,执行计划比spark SQL更优。


spark SQL vs presto

这次没有实际测试impala,比较了presto与impala的原理,两者基本类似,impala同样有stage间的流水线处理。与效率相关的地方,有两点不同,一是impala后端使用c++实现,语言上的效率上限高于presto。二是架构上impala抛弃了主从结构,不像presto只有一个coodinator,而是所有的impalad地位相同,都可以接受查询,解析sql,生成执行计划。当多用户并发查询的时候,效率优势会很明显。

总结一下影响效率的几个点:
1.资源申请、运行环境初始化
hive on mr 有参数可以配置同一个job中的task重用jvm,上图中每一个stage都是一个job,可见效果不会很明显。
hive on tez和spark都有container重用
presto不基于yarn,资源预分配
2.减少数据读写
hive on mr中间结果写hdfs
hive on tez 内存
spark 内存+本地
presto 纯内存
3.减少数据传输
全都做到了local计算
4.并发度
hive on mr 最弱,虽然有hive.exec.parallel,job内有效
hive on tez, 无依赖的vertices 并行执行
spark, 同hive on tez,无依赖的job并行执行
presto
5.执行计划优化
predicate pushdown 都一样
project pushdown 程度上presto > spark > hive
另外这次没提到的影响效率的点还有动态代码生成,文件存储格式,基于代价的执行计划优化等。


最后考虑一下影响查询引擎的效率上限的本质原因:
他们为用户提供的不同程度的灵活性而设计的编程模型的差异。
比如tez比spark慢的第二点,因为tez提供的模型是DAG,由用户自己控制vertex之间的edge,还可以自定义vertex manager。给用户提供了灵活性。而spark 的编程模型是RDD,对于stage的划分,stage到stage的数据交互完全不用向用户开放,因此可以做的效率更高。
而presto更是只提供了sql模型,相比spark不需要把sql先转成RDD,而是直接一体化,怎么快怎么来!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,001评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,210评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,874评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,001评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,022评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,005评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,929评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,742评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,193评论 1 309
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,427评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,583评论 1 346
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,305评论 5 342
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,911评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,564评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,731评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,581评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,478评论 2 352

推荐阅读更多精彩内容