三者概念
RDD(Resilient Distributed DataSet)
弹性分布式数据集,是Spark中最基本的数据处理模型。在代码中是抽象类,代表一个弹性的、不可变、可分区、里面的元素可并行计算的集合。
弹性
存储的弹性:内存与磁盘的自动切换;
容错的弹性:数据丢失可以自动恢复;
计算的弹性:计算出错重试机制;
分片的弹性:可按需重新分片
不可变
RDD封装了计算逻辑不可改变,只能通过产生新的RDD并在新的RDD里面封装计算逻辑以此来改变
数据抽象
是一个抽象类,需要子类具体实现
数据集
不保存数据而是封装计算逻辑
DataFrame
Spark SQL中的DataFrame API 允许我们使用DataFrame而不用必须去注册临时表或者生成SQL表达式。
DataSet
具有强类型的数据集合,需要提供对应的类型信息。
三者版本
Spark1.0 => RDD
Spark1.3 => DataFrame
Spark1.6 => Dataset
同样的数据给到这三种数据结构,其实计算出来的结果相同,只是执行效率和方式不同。而DataSet可能在未来完全取代RDD和DataFrame。
三者共性
①都是spark下的分布式弹性数据集;
②都有惰性机制,也可称为懒加载,也就是说转换操作不立即执行,只有在行动算子操作执行时才会触发运算;
③都有分区概念;
④都会根据内存情况自动缓存运算;
三者区别
①在我们使用spark的机器学习库时,其中前者适用于RDD,而后者使用于DF,DS
ml和mllib都是Spark的机器学习库,不过ml主要操作的是DataFrame, 而mllib操作的是RDD,也就是说二者面向的数据集不一样。相比于mllib在RDD提供的基础操作,ml在DataFrame上的抽象级别更高,数据和操作耦合度更低;
②DF和DS主要是与SparkSQL打交道的,RDD不支持SparkSQL操作;
③相比于RDD,DataFrame遍历的时候每一行固定为Row,需要通过解析才能获取各个字段的值;
④Dataset 和 DataFrame 拥有完全相同的成员函数,区别只是每一行的数据类型不同;DataFrame就是DataSet的一个特例,如下图:
也就是说DataFrame就是每一行类型为Row的DataSet。相比于DataSet,每一行有哪些字段,什么类型无法直接得出。
三者转换
数学排列组合都学过,如果总共三个,两两配对(考虑顺序),就是(1+2)x3=6,那么有6种转换。那么是否都可行呢?
①RDD=>DataFrame(使用.toDF())
val rdd: RDD[(Int, String, Int)] = spark.sparkContext.makeRDD(List((1, "zs", 30), (2, "ls", 40)))
val df: DataFrame = rdd.toDF("id", "name", "age")
②DataFrame=>RDD(使用.rdd)
val rowRDD: RDD[Row] = df.rdd
③RDD=>DataSet(使用模型匹配构建对象然后使用.toDS())
val ds1: Dataset[User] = rdd.map {
case (id, name, age) => {
User(id, name, age)
}
}.toDS()
④DataSet=>RDD(使用.rdd)
val userRDD: RDD[User] = ds1.rdd
⑤DataFrame=>DataSet(调用.as[类],ps:这个类必须字段类型与DF对应)
val ds: Dataset[User] = df.as[User]
⑥DataSet=>DataFrame(使用.toDF())
val df1: DataFrame = ds.toDF()