spark 2.0主要特性预览
Spark 2.0相比老版本变化很大,已经发布了预览版本。原始的英文版databricks的博客:https://databricks.com/blog/2016/05/11/apache-spark-2-0-technical-preview-easier-faster-and-smarter.html
变化点主要有:
1、统一api 到datasets
DataFrame 和 Dataset 的功能是什么?它们都是提供给用户使用,包括各类操作接口的 API。1.3 版本引入 DataFrame,1.6 版本引入 Dataset,2.0 提供的功能是将二者统一,即保留 Dataset,而把 DataFrame 定义为 Dataset[Row],即是 Dataset 里的元素对象为 Row 的一种(SPARK-13485)。
DataFrame,它就是提供了一系列操作 API,与 RDD API 相比较,DataFrame 里操作的数据都是带有 Schema 信息,所以 DataFrame 里的所有操作是可以享受 Spark SQL Catalyst optimizer 带来的性能提升,比如 code generation 以及 Tungsten 等。执行过程如下图所示:
但是 DataFrame 出来后发现有些情况下 RDD 可以表达的逻辑用 DataFrame 无法表达。比如 要对 group by 或 join 后的结果用自定义的函数,可能用 SQL 是无法表达的。如下代码:
case class ClassData(a: String, b: Int)
case class ClassNullableData(a: String, b: Integer)
val ds = Seq(ClassData("a", 1), ClassData("a", 2)).toDS()
val agged = ds.groupByKey(d => ClassNullableData(d.a, null))
.mapGroups {
case (key, values) => key.a + values.map(_.b).sum
}
中间处理过程的数据是自定义的类型,并且 groupby 后的聚合逻辑也是自定义的,故用 SQL 比较难以表达,所以提出了 Dataset API。Dataset API 扩展 DataFrame API 支持静态类型和运行已经存在的 Scala 或 Java 语言的用户自定义函数。同时 Dataset 也能享受 Spark SQL 里所有性能 带来的提升。那么后面发现 Dataset 是包含了 DataFrame 的功能,这样二者就出现了很大的冗余,故在 2.0 时将二者统一,保留 Dataset API,把 DataFrame 表示为 Dataset[Row],即 Dataset 的子集。
因此我们在使用 API 时,优先选择 DataFrame & Dataset,因为它的性能很好,而且以后的优化它都可以享受到,但是为了兼容早期版本的程序,RDD API 也会一直保留着。后续 Spark 上层的库将全部会用 DataFrame,比如 MLlib、Streaming、Graphx 等。
2、全流程code generation
我们看其中一个例子:
select count(*) from store_sales where ss_item_sk = 1000
那么在翻译成计算引擎的执行计划如下图:
而通常物理计划的代码是这样实现的:
class Filter {
def next(): Boolean = {
var found = false
while (!found && child.next()) {
found = predicate(child.fetch())
}
return found
}
def fetch(): InternalRow = {
child.fetch()
}...
}
但是真正如果我们用 hard code 写的话,代码是这样的:
var count = 0
for (ss_item_sk in store_sales) {
if (ss_item_sk == 1000) {
count += 1
}
}
发现二者相关如下图所示:
那么如何使得计算引擎的物理执行速度能达到 hard code 的性能呢?这就提出了 whole-stage code generation,即对物理执行的多次调用转换为代码 for 循环,类似 hard code 方式,减少中间执行的函数调用次数,当数据记录多时,这个调用次数是很大。 最后这个优化带来的性能提升如下图所示:
从 benchmark 的结果可以看出,使用了该特性后各操作的性能都有很大的提升。
tpc-ds的对比测试结果也非常好(spark 1.6对比spark 2.0) :
tpc-ds测试的效果,除流全流程的code generation,还有大量在优化器的优化如空值传递以及对parquet扫描的3倍优化
3、抛弃Dstrem API,新增结构化流api
Spark Streaming 是把流式计算看成一个一个的离线计算来完成流式计算,提供了一套 Dstream 的流 API,相比于其他的流式计算,Spark Streaming 的优点是容错性和吞吐量上要有优势,关于 Spark Streaming 的详细设计思想和分析,可以到 https://github.com/lw-lin/CoolplaySpark 进行详细学习和了解。
在 2.0 以前的版本,用户在使用时,如果有流计算,又有离线计算,就需要用二套 API 去编写程序,一套是 RDD API,一套是 Dstream API。而且 Dstream API 在易用性上远不如 SQL 或 DataFrame。
为了真正将流式计算和离线计算在编程 API 上统一,同时也让 Streaming 作业能够享受 DataFrame/Dataset 上所带来的优势:性能提升和 API 易用,于是提出了 Structured Streaming。最后我们只需要基于 DataFrame/Dataset 可以开发离线计算和流式计算的程序,很容易使得 Spark 在 API 跟业界所说的 DataFlow 来统一离线计算和流式计算效果一样。
比如在做 Batch Aggregation 时我们可以写成下面的代码:
那么对于流式计算时,我们仅仅是调用了 DataFrame/Dataset 的不同函数代码,如下:
最后,在 DataFrame/Dataset 这个 API 上可以完成如下图所示的所有应用:
4、最后 2.0 版本还有一些其他的特性,如:
- 用 SparkSession 替换掉原来的 SQLContext and HiveContext。
- mllib 里的计算用 DataFrame-based API 代替以前的 RDD 计算逻辑。
- 提供更多的分布式R 语言算法。
- 支持ml pipeline持久化
- 更简单,更高性能的Accumulator API
- WordPress高亮插件:Crayon Syntax Highlighter加载优化
- 深入理解 ButterKnife,让你的程序学会写代码
- JS+CSS让网站嗨起来,博客要被玩坏了!
- Linux系统zip压缩命令详细参数,附文件排除选项的正确用法
- 浅谈Android自定义锁屏页的发车姿势
- 移动App入侵与逆向破解技术-iOS篇
- 启用WP Super Cache纯代码版本之后的一些优化措施
- WP Super Cache静态缓存插件纯代码版(兼容多域名网站)
- 【Dev Club分享】React Native项目实战总结。
- HTML 5 视频直播一站式扫盲
- Golang之chan/goroutine
- 原创插件:WordPress博客友好对话框+文章随机推荐滚动条插件(附代码版)
- php平滑重启nginx,彻底清除WordPress的静态缓存
- 解耦---Hybrid H5跨平台性思考
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Apache环境下配置多个ssl证书搭建多个站点的方法
- 详解Linux手动释放缓存的方法
- 详解Centos7源码编译安装 php7.2之生产篇
- Centos7利用内存优化磁盘缓存读写速度的方法
- Redis过期策略和数据淘汰机制
- 图片由彩色渐变到黑白动画
- Kafka如何保证数据可靠性
- ubuntu中snap包的安装、更新删除与简单使用
- 学习在kernel态下使用NEON对算法进行加速的方法
- Centos7上Mesos和Marathon的安装和配置
- Redis高级数据类型-Bitmap和HyperLogLog
- Redis持久化策略
- 在linux下开启FTP服务方法介绍
- Linux中gpio接口的使用方法示例
- Three.js教程(1):初识three.js