一、技术背景

Spark1.x版本中执行SQL语句,使用的是一种最经典,最流行的查询求职策略,该策略主要基于 Volcano Iterator Model(火山迭代模型)。一个查询会包含多个Operator,每个Operator都会实现一个接口,提供一个next()方法,该方法返回Operator Tree的下一个Operator,能够让查询引擎组装任意Operator,而不需要去考虑每个Operator具体的处理逻辑,所以Volcano Iterator Model 才成为了20年中SQL执行引擎最流行的一种标准。

比如如下SQL语句:

select count(*) from employees where salary == 1000

使用Java代码手写实现的SQL功能的代码如下

int count = 0;
for(emp : employees){
if(emp == 1000){
count += 1;
}
}

有人实验了Volcano Iterator Model 方式与直接手写Java代码实现的方式,直接手写Java代码是专门为了实现某个指定的功能而编写的,不具有良好的组装性和扩展性,这两种方式进行了性能的对比结果如下图。

可以看到直接手写Java代码实现某一特定功能的性能比Volcano模型的性能高出了一个数量级,主要的原因有三点:

1. 避免了虚函数调用(Virtual Function Dispatch),Volcano Iterator Model至少需要调用一次next()获取下一个Operator,在操作系统层面会被编译为Virtual Function Dispatch,会执行多个CPU指令,并且速度慢。而直接编写的Java代码中没有任何函数调用逻辑。

2. 使用CPU寄存器存取中间数据 。 Volcano Iterator Model将数据交给下一个Operator时,都需要将数据写入内存缓冲,但是在手写代码中,JVM JIT编译器会将这些数据写入CPU寄存器,CPU直接从寄存器中读写数据比在内存缓冲中读写数据的性能要高一个数量级。

3.编译器Loop Unrolling。手写代码针对某特定功能使用简单循环,而现代的编译器可以自动的对简单循环进行Unrolling,生成单指令多数据流(SIMD),在每次CPU指令执行时处理多条数据。而这些优化特点无法在Volcano Iterator Model复杂的函数调用场景中施展。

二、Whole-stage code generation

1. Spark性能调优思路

在以上论述的技术背景下,如果要对Spark进行性能优化,应该避免使用Volcano模型,在运行时动态生成代码。由此,Spark2.x版本中,基于Tungsten引擎的Whole-stage code generation 技术应运而生。SQL语句编译后的Operator-Tree中,每个Operator不再执行逻辑,而是通过全流式代码生成技术在运行时动态生成代码,并尽量将所有的操作打包到一个函数中。如果是简单查询,Spark会尽量生成一个Stage,如果是复杂的查询,就可能会生成多个Stage。

2. Spark2.x的SQL执行计划

Spark提供了一个explain( )方法来查询SQL的执行计划。

例子:

准备工作:通过saprk读取HDFS上的员工表信息(emp.csv),执行操作如下:

scala> case class Emp(eno:Int,ename:String,job:String,mgr:String,hiredate:String,sal:Int,comm:String,deptno:Int)
defined class Emp scala> val lines = sc.textFile("hdfs://bigdata11:9000/input/emp.csv").map(_.split(","))
lines: org.apache.spark.rdd.RDD[Array[String]] = MapPartitionsRDD[9] at map at <console>:24 scala> val allEmp = lines.map(x => Emp(x(0).toInt,x(1),x(2),x(3),x(4),x(5).toInt,x(6),x(7).toInt))
allEmp: org.apache.spark.rdd.RDD[Emp] = MapPartitionsRDD[10] at map at <console>:28 scala> val empDF = allEmp.toDF
empDF: org.apache.spark.sql.DataFrame = [eno: int, ename: string ... 6 more fields]

  

查看执行计划:通过explain()方法查看执行计划。前面带*号的步骤就是通过whole-stage code generation生成的。

三、总结

从以上分析可以看出Spark2.x引入的whole-stage code generation技术,使Spark2.x的性能比Spark1.x的性能有所提高。但并不是所有的操作都能够大幅提升性能,whole-stage code generation技术是从CPU密集操作的方面进行性能调优,对IO密集操作的层面是无法提高效率的,比如Shuffle中产生的读写磁盘操作是无法通过该技术提升性能的,Spark未来版本的更新还需要从IO密集操作层面进行性能调优。

【Spark】Spark性能优化之Whole-stage code generation的更多相关文章

  1. SparkSQL的一些用法建议和Spark的性能优化

    1.写在前面 Spark是专为大规模数据处理而设计的快速通用的计算引擎,在计算能力上优于MapReduce,被誉为第二代大数据计算框架引擎.Spark采用的是内存计算方式.Spark的四大核心是Spa ...

  2. [看图说话] 基于Spark UI性能优化与调试——初级篇

    Spark有几种部署的模式,单机版.集群版等等,平时单机版在数据量不大的时候可以跟传统的java程序一样进行断电调试.但是在集群上调试就比较麻烦了...远程断点不太方便,只能通过Log的形式,进行分析 ...

  3. Spark实践 -- 性能优化基础

    性能调优相关的原理讲解.经验总结: 掌握一整套Spark企业级性能调优解决方案:而不只是简单的一些性能调优技巧. 针对写好的spark作业,实施一整套数据倾斜解决方案:实际经验中积累的数据倾斜现象的表 ...

  4. spark mongo 性能优化

    性能优化事项 http://www.mongoing.com/wp-content/uploads/2016/08/MDBSH2016/TJ_MongoDB+Spark.pdf MongoDB + S ...

  5. Spark SQL 性能优化再进一步:CBO 基于代价的优化

    摘要: 本文将介绍 CBO,它充分考虑了数据本身的特点(如大小.分布)以及操作算子的特点(中间结果集的分布及大小)及代价,从而更好的选择执行代价最小的物理执行计划,即 SparkPlan. Spark ...

  6. Spark Streaming性能优化: 如何在生产环境下应对流数据峰值巨变

    1.为什么引入Backpressure 默认情况下,Spark Streaming通过Receiver以生产者生产数据的速率接收数据,计算过程中会出现batch processing time > ...

  7. Spark Streaming性能优化系列-怎样获得和持续使用足够的集群计算资源?

    一:数据峰值的巨大影响 1. 数据确实不稳定,比如晚上的时候訪问流量特别大 2. 在处理的时候比如GC的时候耽误时间会产生delay延迟 二:Backpressure:数据的反压机制 基本思想:依据上 ...

  8. 《Spark大数据处理:技术、应用与性能优化 》

    基本信息 作者: 高彦杰 丛书名:大数据技术丛书 出版社:机械工业出版社 ISBN:9787111483861 上架时间:2014-11-5 出版日期:2014 年11月 开本:16开 页码:255 ...

  9. 《Spark大数据处理:技术、应用与性能优化》【PDF】 下载

    内容简介 <Spark大数据处理:技术.应用与性能优化>根据最新技术版本,系统.全面.详细讲解Spark的各项功能使用.原理机制.技术细节.应用方法.性能优化,以及BDAS生态系统的相关技 ...

随机推荐

  1. CFileDialog 多文件选择

    CString pathName = _T(""); CString fileName = _T(""); CString strMulfilepath = _ ...

  2. latex 调整间隔

    转自:http://blog.sina.com.cn/s/blog_4a4927c70100phsb.html,感谢分享! 一.LATEX调整公式与正文间距离,调整空白大小:   调整空白命令: \s ...

  3. Glide实现查看图片和保存图片到手机

    两种方式, 推荐方式一 方式一 downloadOnly 创建一个 ImageActivity public class ImageActivity extends AppCompatActivity ...

  4. Android错题集

    在Android学习的过程中,遇到过很多迷之问题,在这里记下以防以后忘记,也可以顺便帮助一下遇到了相同问题的朋友. 1.自定义控件文字大小错误: 在自定义控件中获取的getDimension值为px值 ...

  5. dctcp example-ns2

    set N 8 set B 250 set K 65 set RTT 0.0001 set simulationTime 1.0 set startMeasurementTime 1 set stop ...

  6. LeetCode-Container With Most Water-zz

    先上代码. #include <iostream> #include <vector> #include <algorithm> using namespace s ...

  7. Linux命令 标签: linux 2016-08-01 10:26 508人阅读 评论(0) 收藏

    Linux常用命令 文件.目录的基本操作 ls - 查看文件 cp - 拷贝文件 mv - 移动或重命名文件 rm - 删除文件 touch - 创建空文件或更新文件时间 cd - 改变当前路径 pw ...

  8. July 06th 2017 Week 27th Thursday

    Knowledge is the antidote to fear. 知识可以解除恐惧. Fear always steps from unknown things. Once we know wha ...

  9. Android Studio 独立引入(非友盟)微博分享和回调时问题

    最近同事在做一个小项目时,由于产品的要求,Wap页面的分享规定不能使用友盟的社会化组件.他则不得不手动一个一个渠道的引入分享,好在渠道不多就三个,但是第一微博分享引入的时候问题就出现了. 问题一:li ...

  10. PHP----练习------球队列表

    题目:页面上有一个ul球队列表当鼠标移动到某个li上的时候改行背景颜色变红,当点击某个li的时候,让该li之前的所有li背景色变黄,之后的所有li背景色变蓝.自己不变色. <!DOCTYPE h ...