Spark RDD DF DS 的区别与联系
三者的联系
1)都是spark中得弹性分布式数据集,轻量级
2)都是惰性机制,延迟计算
3)根据内存情况,自动缓存,加快计算速度
4)都有partition分区概念
5)众多相同得算子:map flatmap 等等
三者的区别
-
RDD
- 优点: 编译时类型安全 编译时就能检查出类型错误 面向对象的编程风格 直接通过类名点的方式来操作数据
- 缺点: 序列化和反序列化的性能开销 无论是集群间的通信, 还是IO操作都需要对对象的结构和数据进行序列化和反序列化 GC的性能开销
频繁的创建和销毁对象, 势必会增加GC -
DataFrameDataFrame引入了schema和off-heap
- schema : RDD每一行的数据, 结构都是一样的.
这个结构就存储在schema中. Spark通过schame就能够读懂数据, 因此在通信和IO时就只需要序列化和反序列化数据,
而结构的部分就可以省略了.- off-heap : 意味着JVM堆以外的内存,
这些内存直接受操作系统管理(而不是JVM)。Spark能够以二进制的形式序列化数据(不包括结构)到off-heap中, 当要操作数据时,
就直接操作off-heap内存. 由于Spark理解schema, 所以知道该如何操作 其API不是面向对象的
这里我们就可以看出spark为了解决RDD的问题进行的取舍
val idAgeRow = spark.sparkContext.parallelize(Seq(Row(1, 70), Row(2, 29), Row(4, 21)))
val schema = StructType(Array(StructField("id", DataTypes.IntegerType), StructField("age", DataTypes.IntegerType)))
val idAgeDF = spark.sqlContext.createDataFrame(idAgeRow, schema)
import spark.implicits._
//可以看出此处API不是面向对象的!
idAgeDF.filter($"age" > 25).show()
//即使你洗了错误的类型编译时候也不会报错!运行时报错!
idAgeDF.filter($"age" > 'a').show()
- RDD是分布式的Java对象的集合。DataFrame是分布式的Row对象的集合
- DataFrame除了提供了比RDD更丰富的算子以外,更重要的特点是提升执行效率、减少数据读取以及执行计划的优化,比如filter下推、裁剪等
- Dataset和DataFrame拥有完全相同的成员函数,区别只是每一行的数据类型不同
- DataFrame也可以叫Dataset[Row],每一行的类型是Row,不解析,每一行究竟有哪些字段,各个字段又是什么类型都无从得知,只能用getAS方法或者共性中的第七条提到的模式匹配拿出特定字段
- 而Dataset中,每一行是什么类型是不一定的,在自定义了case class之后可以很自由的获得每一行的信息
三者可以相互转化
1)DF/DS转RDD
Val Rdd = DF/DS.rdd
2) DS/RDD转DF
import spark.implicits._
调用 toDF(就是把一行数据封装成row类型)
3)RDD转DS
将RDD的每一行封装成样例类,再调用toDS方法
4)DF转DS
根据row字段定义样例类,再调用asDS方法[样例类]
特别注意:在使用一些特殊的操作时,一定要加上 import spark.implicits._ 不然toDF、toDS无法使用