弹性分布式数据集,是Spark中最基本的数据处理模型。在代码中是抽象类,代表一个弹性的、不可变、可分区、里面的元素可并行计算的集合。
弹性存储的弹性:内存与磁盘的自动切换;
容错的弹性:数据丢失可以自动恢复;
计算的弹性:计算出错重试机制;
分片的弹性:可按需重新分片
不可变RDD封装了计算逻辑不可改变,只能通过产生新的RDD并在新的RDD里面封装计算逻辑以此来改变
数据抽象是一个抽象类,需要子类具体实现
数据集不保存数据而是封装计算逻辑
DataframeSpark 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()