1.1背景
从Spark1.3.0版本开始推出DataFrame,DataFrame让Spark具备了处理大规模结构化数据的能力,在比原有的RDD转化方式易用的前提下,计算性能更快。发布DataFrame之后开发者收到了很多反馈,其中一个主要的是大家反映缺乏编译时类型安全。为了解决这个问题,Spark采用新的 Dataset API (DataFrame API的类型扩展)。
从Spark1.6.0版本开始引入Dataset,Dataset API扩展DataFrame API,支持静态类型和运行已经存在的Scala或Java语言的用户自定义函数。对比传统的RDD API,Dataset API提供更好的内存管理,特别是在长任务中有更好的性能提升。
Dataset 效率的提升主要是得益于Tungsten项目,Tungsten项目是Spark内核级别的优化。Tungsten做的优化就是由Spark自己来管理内存而不是使用JVM,这样可以避免JVM GC带来的性能损失;内存中的Java对象被存储成Spark自己的二进制格式,更加紧凑,节省内存空间,而且能更好的估计数据量大小和内存使用情况;计算直接发生在二进制格式上,省去了序列化和反序列化时间。
1.2 Dataset数据集的使用
Dataset 是一个强类型的、不可变的对象集合。DataSets的API核心是一个新的编码器,编码器的作用是将JVM的对象与表结构进行转换。表结构采用的Tungsten的二进制格式存储,允许操作序列化数据,提高内存利用率。Spark1.6附带支持各种类型的自动编码器,包括原始类型(如字符串、整数、长整数),Scala case类,和Javabean。
Dataset的API与RDD的API类似,它也提供了许多相同的转换操作(如map、flatMap、filter)。例如下面的代码,读取一个文本文件并进行分词操作:
RDDs val lines = sc.textFile("/wikipedia") val words = lines .flatMap(_.split(" ")) .filter(_ != "") |
Datasets val lines = sqlContext.read.text("/wikipedia").as[String] val words = lines |