spark的抽象数据集包括RDD、DataFrame、Dataset,其实就是三种API,理一下这几个东西的异同,适用场景。
RDD
首先RDD是spark最早提供给开发者的一种API,RDD即 Resilient Distributed Datase 弹性分布式数据集,意味着RDD的数据是分布在不同的机器上的,一台机器即一个分区。
通过map等算子,可以在每台机器上对数据做相同的操作;通过reduce等算子,可以将不同机器上的数据重新洗牌进行一个聚合,这个过程叫做shuffle,其间会发生机器之间数据传输,所以是比较消耗资源的;还有可以通过collect等算子将数据拉到driver端,driver端即提交任务的机器,所以有collect算子时是要注意driver端内存分配的。
另外,需要知道的是RDD是不可变的,我们对rdd操作的算子不是修改rdd的数据,而是把一个RDD转化为另一个RDD。
DataFrame
DataFrame和RDD其实是类似的东西,不同的是DataFrame支持SparkSQL,这就意味着DataFrame里面的是结构化数据,但是DataFrame的字段类型约束不是严格的,它每一行的类型为row,所以每一列的值无法直接访问,还需要解析,来看下面两个例子:
1.row对象可以直接通过getAS方法获取每个列的值
2.也可以用匹配模式定义一个有具体列信息的Row对象
DataSet
DataSet的每一个字段类型都需要通过case class事先定义好,取值的时候就非常方便了,遗憾的是貌似目前还不支持Python和R,同样,来看一个例子
我们需要事先通过case class来定义好这个row的字段名和类型
在rdd转化为dataset调用toDS方法之前要把每一列的值装载到Row对象中,接下来对这个dataset的数据就可以直接用line.col1获取了。
看起来DataSet和DataFrame的差别不是很大,确实是这样的,因为DataFrame就是Dataset[Row],每一行的类型是Row,而且后期DataFrame已接近要被抛弃了,使用Dataset[Row]来代替。
转化
RDD、DataFrame、Dataset三者都用不同的适用场景,所以开发者会不可避免地需要将他们互相转换。
上面已经说了 RDD -> DataSet 的方式,下面补充下剩下的几个转换
- DataFrame -> RDD
简单:dataFrame.rdd
- DataSet -> RDD
So easy : dataSet.rdd
- DataSet -> DataFrame
仍然so easy,因为只需要把dataSet存的对象转换成Row,但是注意要导入隐式转换的包。
- RDD -> DataFrame
这里可以事先定义好列名,当然也可以先不定义,之后用case class来指定列名
- DataFrame -> Dataset
因为上面说了其实dataFrame就是特殊的dataSet,所以只需要吧每一行的row类型转化成行对象,加上列名和类型即可。