Spark 相关

一、Spark SQL相关

1.spark sql 要比shark 快的几点:

A.内存列存储,有点像parquet或者orc等列式存储格式,存储效率高

B.字节码生成技术,主要是避免了虚函数的调用,转变成了scala函数映射,在sql语句执行的时候,具体方法执行(例如 sort中的compare)会调用虚函数,虚函数调用会导致指令集预读失效,因为虚函数后面的指令集不是马上要执行的,导致cpu需要被暂停一下,这里给出相关的网址:Spark SQL Codegen介绍

C.scala代码优化

A:内存列存储(In-Memory Columnar Storage)
      sparkSQL的表数据在内存中存储不是采用原生态的JVM对象存储方式,而是采用内存列存储,如下图所示。

 

      该存储方式无论在空间占用量和读取吞吐率上都占有很大优势。

      对于原生态的JVM对象存储方式,每个对象通常要增加12-16字节的额外开销,对于一个270MB的TPC-H lineitem table数据,使用这种方式读入内存,要使用970MB左右的内存空间(通常是2~5倍于原生数据空间);另外,使用这种方式,每个数据记录产生一个JVM对象,如果是大小为200B的数据记录,32G的堆栈将产生1.6亿个对象,这么多的对象,对于GC来说,可能要消耗几分钟的时间来处理(JVM的垃圾收集时间与堆栈中的对象数量呈线性相关)。显然这种内存存储方式对于基于内存计算的spark来说,很昂贵也负担不起。

      对于内存列存储来说,将所有原生数据类型的列采用原生数组来存储,将Hive支持的复杂数据类型(如array、map等)先序化后并接成一个字节数组来存储。这样,每个列创建一个JVM对象,从而导致可以快速的GC和紧凑的数据存储;额外的,还可以使用低廉CPU开销的高效压缩方法(如字典编码、行长度编码等压缩方法)降低内存开销;更有趣的是,对于分析查询中频繁使用的聚合特定列,性能会得到很大的提高,原因就是这些列的数据放在一起,更容易读入内存进行计算。



B:字节码生成技术(bytecode generation,即CG)
      在数据库查询中有一个昂贵的操作是查询语句中的表达式,主要是由于JVM的内存模型引起的。比如如下一个查询:

  1. SELECT a + b FROM table  
复制代码


在这个查询里,如果采用通用的SQL语法途径去处理,会先生成一个表达式树(有两个节点的Add树,参考后面章节),在物理处理这个表达式树的时候,将会如图所示的7个步骤:
  • 调用虚函数Add.eval(),需要确认Add两边的数据类型
  • 调用虚函数a.eval(),需要确认a的数据类型
  • 确定a的数据类型是Int,装箱
  • 调用虚函数b.eval(),需要确认b的数据类型
  • 确定b的数据类型是Int,装箱
  • 调用Int类型的Add
  • 返回装箱后的计算结果

其中多次涉及到虚函数的调用,虚函数的调用会打断CPU的正常流水线处理,减缓执行。
      Spark1.1.0在catalyst模块的expressions增加了codegen模块,如果使用动态字节码生成技术(配置spark.sql.codegen参数),sparkSQL在执行物理计划的时候,对匹配的表达式采用特定的代码,动态编译,然后运行。如上例子,匹配到Add方法:

 

然后,通过调用,最终调用:
 

最终实现效果类似如下伪代码:
  1. val a: Int = inputRow.getInt(0)  
  2. val b: Int = inputRow.getInt(1)  
  3. val result: Int = a + b  
  4. resultRow.setInt(0, result)  
复制代码


对于Spark1.1.0,对SQL表达式都作了CG优化,具体可以参看codegen模块。CG优化的实现主要还是依靠scala2.10的运行时放射机制(runtime reflection)。对于SQL查询的CG优化,可以简单地用下图来表示:
 

C:scala代码优化
      另外,sparkSQL在使用Scala编写代码的时候,尽量避免低效的、容易GC的代码;尽管增加了编写代码的难度,但对于用户来说,还是使用统一的接口,没受到使用上的困难。下图是一个scala代码优化的示意图:

2.Spark SQL应用

苏宁大数据应用

出处了一篇苏宁Spark SQL的应用文章,其中两个地方比较有意思:

a. spark sql + jdbc 来代替sqoop,这可能跟它的业务需求有关,原始DB里的数据不需要存储到hdfs、hive或者hbase中,直接就使用spark sql+jdbc进行数据的清洗和计算了

b. driver 并行优化,提前使用action操作来触发数据的加载操作

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值