一、技术背景

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. 佛系结对编程---四则运算(Core 第四组)

    ----by core 第四组 ( 邹卫其 范力 ) 一. 项目介绍 1. 能自动生成小学四则运算题目并给出答案,生成题目时可以选择下列参数:   1)生成题目数量   2)每道题目中运算数数量   ...

  2. 浏览器环境下的javascript DOM对象继承模型

    这张图是我直接在现代浏览器中通过prototype原型溯源绘制的一张浏览器宿主环境下的javascript DOM对象模型,对于有效学习和使用javascript DOM编程起到高屋建瓴的指导作用, ...

  3. HTML5时代的纯前端上传图片预览及严格图片格式验证函数(转载)

    原文地址:http://www.2cto.com/kf/201401/274752.html 一.要解决什么样的问题? 在写这个函数之前,有们童鞋在群里问如何纯前端严格验证图片格式.这在html5时代 ...

  4. C++ inheritance examples

    1.C++继承经典例子 #include <iostream> using namespace std; class Base { private: int b_number; publi ...

  5. kvm虚拟机shutdown命令不起作用

    使用 virsh shutdown vmhost 发现虚拟机没有关闭,命令没有起作用. 只能使用 virsh destroy vmhost 来强制关闭虚拟机 解决: 在vmhost虚拟机里面安装acp ...

  6. 你是怎么调试 JavaScript 程序

    你是怎么调试 JavaScript 程序的?最原始的方法是用 alert() 在页面上打印内容,稍微改进一点的方法是用 console.log() 在 JavaScript 控制台上输出内容.嗯~,用 ...

  7. U-Mail邮件群发如何过滤无效地址?

    U-Mail邮件群发平台可以自动过滤掉无效和重复地址,过滤效果如下图 U-Mail邮件群发平台会将客户已经确认好是无效地址的加入无效地址库,下次再导入改无效地址就直接拒绝.邮件格式不正确的也会直接过滤 ...

  8. python UI自动化实战记录三:pageobject-基类

    脚本思路: 使用pageobject模式,写一个basepage基类,所有页面的通用方法封装到基类中.比如打开页面,关闭页面,等待时间,鼠标移到元素上,获取单个元素,获取一组元素,获取元素的子元素,截 ...

  9. ORACLE查询删除重复记录

     比如现在有一人员表 (表名:peosons) 若想将姓名.身份证号.住址这三个字段完全相同的记录查询出来 复制代码 代码如下: select p1.*   from persons  p1,pers ...

  10. 实现websocket

    转:http://www.cnblogs.com/dolphinX/p/3462898.html 在之前的博客中提到过看到html5 的websocket后很感兴趣,终于可以摆脱长轮询(websock ...