目录
1.绪论
2.概念
2.1什么是RDD?
2.2什么是DataFrame?
2.3什么是DataSet?
3.RDD、DataFrame、DataSet区别与联系
3.1区别
3.2联系
4.RDD、DataFrame、DataSet间的相互转换
1.绪论
在Spark中,有三个针对数据的抽象结构:RDD、FataFrame、DataSet;
RDD、DataFrame、DataSet全都是spark平台下的分布式弹性数据集,为处理超大型数据提供便利;
2.概念
2.1什么是RDD?
Spark RDD:RDD (Resilient Distributed Dataset) 叫做弹性分布式数据集,它归属于SpqrkCore模块中,是Spark中最基本的数据抽象,代码中RDD是一个抽象类,它代表一个弹性的、不可变、可分区、里面的元素可并行计算的集合。并且RDD表示只读的分区的数据集,对RDD进行改动,只能通过RDD的转换操作来进行。
2.2什么是DataFrame?
Spark DataFrame:与RDD不同,数据以列的形式组织起来,类似于关系数据库中的表。它是一个不可变的分布式数据集合, Spark中的DataFrame允许开发人员将数据结构(类型)加到分布式数据集合上,从而实现更高级别的抽象。即DataFrame它里面是结构化的信息包含了每一列的字段名和类型,这让SparkSql可以很方便的清楚了数据的具体信息,提升了任务的执行效率。 DataFrame的前身是SchemaRDD。Spark1.3更名为DataFrame。不继承RDD,自己实现了RDD的大部分功能。
DataFrame特点:
1)DataFrame可以看做分布式 Row 对象的集合,提供了由列组成的详细模式信息,使其可以得到优化。DataFrame 不仅有比RDD更多的算子,还可以进行执行计划的优化。
2)DataFrame更像传统数据库的二维表格,除了数据以外,还记录数据的结构信息,即schema。
3)DataFrame也支持嵌套数据类型(struct、array和map)。
4)DataFrame API提供的是一套高层的关系操作,比函数式的RDD API要更加友好,门槛更低。
5)Dataframe的劣势在于在编译期缺少类型安全检查,导致运行时出错。
2.3什么是DataSet?
Spark DataSet:Apache Spark中的Dataset是DataFrame API的扩展,它提供了类型安全(type-safe),面向对象(object-oriented)的编程接口。 Dataset利用Catalyst optimizer可以让用户通过类似于sql的表达式对数据进行查询。
Spark DataSet特点:
1)DataSet是在Spark1.6中添加的新的接口。
2)与RDD相比,保存了更多的描述信息,概念上等同于关系型数据库中的二维表。
3)与DataFrame相比,保存了类型信息,是强类型的,提供了编译时类型检查。
4)调用Dataset的方法先会生成逻辑计划,然后Spark的优化器进行优化,最终生成物理计划,然后提交到集群中运行。
5)DataSet包含了DataFrame的功能,在Spark2.0中两者得到了统一:DataFrame表示为DataSet[Row],即DataSet的子集。
3.RDD、DataFrame、DataSet区别与联系
3.1区别
a.schema信息:
RDD中的数据是没有数据类型的
DataFrame中的数据是弱数据类型,不会做数据类型检查
DataSet中的数据类型是强数据类型
b.序列化机制:
RDD和DataFrame默认的序列化机制是java的序列化,可以修改为Kyro的机制
DataSet使用自定义的数据编码器进行序列化和反序列化
c.从版本的产生上来看
RDD(Spark1.0)—>Dataframe(Spark1.3)—>Dataset(Spark1.6)
3.2联系
a.RDD、DataFrame、DataSet都是分布式的弹性数据集,是对处理的数据的一种抽象。
b.都有 惰性机制,在 转化操作 时,不会立即执行,只有在遇到 行动操作 时才会开始计算。
c.都会根据Spark内存情况自动缓存运算,即使数据量很大也不用担心内存溢出问题。
d.都有partition分区的概念。
e.有许多共同的函数,例如filter、map等。
f.RDD适用于迭代计算和数据这一类的操作,处理结构化的数据一般用DataFrame和DataSet。
4.RDD、DataFrame、DataSet间的相互转换
RDD与DataFrame之间的互相转换Spark SQL支持两种RDDs转换为DataFrames的方式:
①使用反射获取RDD内的Schema。当已知类的Schema的时候,使用这种基于反射的方法会让代码更加简洁而且效果也很好。
②通过编程接口指定Schema。通过Spark SQL的接口创建RDD的Schema,这种方式会让代码比较冗长。这种方法的好处是,在运行时才知道数据的列以及列的类型的情况下,可以动态生成Schema。
DataFrame、Dataset转RDD:
val rdd1 = testDF.rdd
val rdd2 = testDS.rdd
RDD转DataFrame:
import ss.implicits._
val testDF = rdd.map(line => (line._1, line._2)).toDF("name", "age")
注:一般使用元组把一行的数据写在一起,然后在toDF中指定字段名
RDD转Dataset:
import ss.implicits._
case class Person(name:String, age: Int) extends Serializable
var personDS = rdd.map(line => Person(line._1, line._2)).toDS
Dataset转DataFrame:
import ss.implicits._
val testDF = testDS.toDF
DataFrame转Dataset:
import ss.implicits._
case class Person(name:String, age: Int) extends Serializable
var personDS = testDF.as[Person]