spark的数据结构 RDD——DataFrame——DataSet区别
转载自:http://blog.csdn.net/wo334499/article/details/51689549
RDD
优点:
- 编译时类型安全
编译时就能检查出类型错误 - 面向对象的编程风格
直接通过类名点的方式来操作数据
缺点:
- 序列化和反序列化的性能开销
无论是集群间的通信, 还是IO操作都需要对对象的结构和数据进行序列化和反序列化. - GC的性能开销
频繁的创建和销毁对象, 势必会增加GC
import org.apache.spark.sql.SQLContext
import org.apache.spark.{SparkConf, SparkContext}
object Run {
def main(args: Array[String]) {
val conf = new SparkConf().setAppName("test").setMaster("local")
val sc = new SparkContext(conf)
sc.setLogLevel("WARN")
val sqlContext = new SQLContext(sc)
/**
* id age
* 1 30
* 2 29
* 3 21
*/
case class Person(id: Int, age: Int)
val idAgeRDDPerson = sc.parallelize(Array(Person(1, 30), Person(2, 29), Person(3, 21)))
// 优点1
// idAge.filter(_.age > "") // 编译时报错, int不能跟String比
// 优点2
idAgeRDDPerson.filter(_.age > 25) // 直接操作一个个的person对象
}
}
DataFrame
DataFrame引入了schema和off-heap
schema : RDD每一行的数据, 结构都是一样的. 这个结构就存储在schema中. Spark通过schame就能够读懂数据, 因此在通信和IO时就只需要序列化和反序列化数据, 而结构的部分就可以省略了.
off-heap : 意味着JVM堆以外的内存, 这些内存直接受操作系统管理(而不是JVM)。Spark能够以二进制的形式序列化数据(不包括结构)到off-heap中, 当要操作数据时, 就直接操作off-heap内存. 由于Spark理解schema, 所以知道该如何操作.
off-heap就像地盘, schema就像地图, Spark有地图又有自己地盘了, 就可以自己说了算了, 不再受JVM的限制, 也就不再收GC的困扰了.
通过schema和off-heap, DataFrame解决了RDD的缺点, 但是却丢了RDD的优点. DataFrame不是类型安全的, API也不是面向对象风格的.
import org.apache.spark.sql.types.{DataTypes, StructField, StructType}
import org.apache.spark.sql.{Row, SQLContext}
import org.apache.spark.{SparkConf, SparkContext}
object Run {
def main(args: Array[String]) {
val conf = new SparkConf().setAppName("test").setMaster("local")
val sc = new SparkContext(conf)
sc.setLogLevel("WARN")
val sqlContext = new SQLContext(sc)
/**
* id age
* 1 30
* 2 29
* 3 21
*/
val idAgeRDDRow = sc.parallelize(Array(Row(1, 30), Row(2, 29), Row(4, 21)))
val schema = StructType(Array(StructField("id", DataTypes.IntegerType), StructField("age", DataTypes.IntegerType)))
val idAgeDF = sqlContext.createDataFrame(idAgeRDDRow, schema)
// API不是面向对象的
idAgeDF.filter(idAgeDF.col("age") > 25)
// 不会报错, DataFrame不是编译时类型安全的
idAgeDF.filter(idAgeDF.col("age") > "")
}
}
DataSet
DataSet结合了RDD和DataFrame的优点, 并带来的一个新的概念Encoder
当序列化数据时, Encoder产生字节码与off-heap进行交互, 能够达到按需访问数据的效果, 而不用反序列化整个对象. Spark还没有提供自定义Encoder的API, 但是未来会加入.
下面看DataFrame和DataSet在2.0.0-preview中的实现
下面这段代码, 在1.6.x中创建的是DataFrame
// 上文DataFrame示例中提取出来的
val idAgeRDDRow = sc.parallelize(Array(Row(1, 30), Row(2, 29), Row(4, 21)))
val schema = StructType(Array(StructField("id", DataTypes.IntegerType), StructField("age", DataTypes.IntegerType)))
val idAgeDF = sqlContext.createDataFrame(idAgeRDDRow, schema)
但是同样的代码在2.0.0-preview中, 创建的虽然还叫DataFrame
// sqlContext.createDataFrame(idAgeRDDRow, schema) 方法的实现, 返回值依然是DataFrame
def createDataFrame(rowRDD: RDD[Row], schema: StructType): DataFrame = {
sparkSession.createDataFrame(rowRDD, schema)
}
但是其实却是DataSet, 因为DataFrame被声明为Dataset[Row]
package object sql {
// ...省略了不相关的代码
type DataFrame = Dataset[Row]
}
因此当我们从1.6.x迁移到2.0.0的时候, 无需任何修改就直接用上了DataSet.
下面是一段DataSet的示例代码
import org.apache.spark.sql.types.{DataTypes, StructField, StructType}
import org.apache.spark.sql.{Row, SQLContext}
import org.apache.spark.{SparkConf, SparkContext}
object Test {
def main(args: Array[String]) {
val conf = new SparkConf().setAppName("test").setMaster("local") // 调试的时候一定不要用local[*]
val sc = new SparkContext(conf)
val sqlContext = new SQLContext(sc)
import sqlContext.implicits._
val idAgeRDDRow = sc.parallelize(Array(Row(1, 30), Row(2, 29), Row(4, 21)))
val schema = StructType(Array(StructField("id", DataTypes.IntegerType), StructField("age", DataTypes.IntegerType)))
// 在2.0.0-preview中这行代码创建出的DataFrame, 其实是DataSet[Row]
val idAgeDS = sqlContext.createDataFrame(idAgeRDDRow, schema)
// 在2.0.0-preview中, 还不支持自定的Encoder, Row类型不行, 自定义的bean也不行
// 官方文档也有写通过bean创建Dataset的例子,但是我运行时并不能成功
// 所以目前需要用创建DataFrame的方法, 来创建DataSet[Row]
// sqlContext.createDataset(idAgeRDDRow)
// 目前支持String, Integer, Long等类型直接创建Dataset
Seq(1, 2, 3).toDS().show()
sqlContext.createDataset(sc.parallelize(Array(1, 2, 3))).show()
}
}
spark的数据结构 RDD——DataFrame——DataSet区别的更多相关文章
- APACHE SPARK 2.0 API IMPROVEMENTS: RDD, DATAFRAME, DATASET AND SQL
What’s New, What’s Changed and How to get Started. Are you ready for Apache Spark 2.0? If you are ju ...
- sparkSQL中RDD——DataFrame——DataSet的区别
spark中RDD.DataFrame.DataSet都是spark的数据集合抽象,RDD针对的是一个个对象,但是DF与DS中针对的是一个个Row RDD 优点: 编译时类型安全 编译时就能检查出类型 ...
- java spark list 转为 RDD 转为 dataset 写入表中
package com.example.demo; import java.util.ArrayList; import java.util.Arrays; import java.util.Hash ...
- spark rdd df dataset
RDD.DataFrame.DataSet的区别和联系 共性: 1)都是spark中得弹性分布式数据集,轻量级 2)都是惰性机制,延迟计算 3)根据内存情况,自动缓存,加快计算速度 4)都有parti ...
- RDD, DataFrame or Dataset
总结: 1.RDD是一个Java对象的集合.RDD的优点是更面向对象,代码更容易理解.但在需要在集群中传输数据时需要为每个对象保留数据及结构信息,这会导致数据的冗余,同时这会导致大量的GC. 2.Da ...
- Spark(十六)DataSet
Spark最吸引开发者的就是简单易用.跨语言(Scala, Java, Python, and R)的API. 本文主要讲解Apache Spark 2.0中RDD,DataFrame和Dataset ...
- Spark提高篇——RDD/DataSet/DataFrame(一)
该部分分为两篇,分别介绍RDD与Dataset/DataFrame: 一.RDD 二.DataSet/DataFrame 先来看下官网对RDD.DataSet.DataFrame的解释: 1.RDD ...
- Spark提高篇——RDD/DataSet/DataFrame(二)
该部分分为两篇,分别介绍RDD与Dataset/DataFrame: 一.RDD 二.DataSet/DataFrame 该篇主要介绍DataSet与DataFrame. 一.生成DataFrame ...
- Spark SQL 之 RDD、DataFrame 和 Dataset 如何选择
引言 Apache Spark 2.2 以及以上版本提供的三种 API - RDD.DataFrame 和 Dataset,它们都可以实现很多相同的数据处理,它们之间的性能差异如何,在什么情况下该选用 ...
随机推荐
- 推荐一个Oracle数据库学习网站
推荐一个我个人的Oracle数据库学习网站,比较系统性的整理,会持续更新的网站.网址: Oracle基础教程: http://www.oraclejsq.com/article/010100110.h ...
- flashback query闪回数据
误删除了部分重要数据,已提交,需要恢复.首先尝试flashback query闪回数据. 数据库运行在归档模式,首先确认数据库的SCN的变化: SQL> col fscn for 9999999 ...
- web前端开发插件(无需重复造轮子)
1.artdialog 对话框组件 简介:是一个基于JavaScript编写的对话框组件,他拥有精致的界面与友好的接口 文档链接:http://www.daimajiayuan.com/downloa ...
- 浅谈 Virtual DOM 的那些事
背景 我们都知道频繁的dom给我们带来的代价是昂贵的,例如我们有时候需要去更新Table 的部分数据,必须去重新重绘表格,这代价实在是太大了,相比于频繁的手动去操作dom而带来性能问题,vdom很好的 ...
- BZOJ 4520: [Cqoi2016]K远点对(k-d tree)
Time Limit: 30 Sec Memory Limit: 512 MBSubmit: 1162 Solved: 618[Submit][Status][Discuss] Descripti ...
- e.currentTarget与e.target
e.currentTarget指的是注册了事件监听器的对象,而e.target指的是该对象里的子对象 html中 <div id="addBtn" v-on:click= ...
- 随记181120Service Fabric问题
https://github.com/Azure/service-fabric-issues/issues/1056 不能启动node one /five 问题
- 文件句柄W模式
f1=open('lo',encoding='utf-8',mode='w')f1.write('w4567')print(f1.tell())f1.close() #tell 告诉指针的位置(按字节 ...
- less-7
题目是要求导出文件GET字符型注入 看看代码 这里可以使用报错注入 先按要求用导出文件做 导出文件就是可以向服务器写入文件,但是利用的时候要知道数据库,网站的路径 我们现在less-1查看 www目录 ...
- mysql5.6升级为mysql5.7部署jboss/wildfly应用项目
一.部署mysql5.7二进制版 解压tar -xvf mv mysql-5.7 /usr/local/mysql5.7 或者其他文件夹 cd /usr/local/mysql.57 usera ...