Apache Spark APIs:RDDs,DataFrames,and Datasets

一.Resilient Distributed Dataset(RDD,弹性分布式数据集)

RDD是过去的Spark中最主要的面向用户的API。RDD是数据元素的不可变的分布式集合,在集群中的节点上进行分区,它提供了低级的API,其中包括转换操作和行动操作,这些都是可以并行的。

什么时候使用RDD?

1.你希望在数据集上进行低等级的转换和行动操作
2.你的数据是非结构化的,例如媒体流或文件流
3.你希望使用函数式编程而不是领域特定表达式来操作数据
4.你可以放弃使用结构化和半结构化的DataFrame和DataSet所带来的一些优化和性能优化。

Apache Spark 2.0中RDD发生了什么?

你可能会问:RDD是否已经退化成了二等公民?他们是否已经被弃用了?
回答是:NO!!!
此外,正如你将在下面注意到的,你可以在RDD和DataFrame和DataSet间进行随意转换,通过简单的API方法调用,且DataFrame和DataSet构建在RDD之上。

二.DataFrame

和RDD一样,DataFrame也是一个不可变的分布式数据集合。但不同于RDD,数据被组织成命名的列,就像一个关系型数据库中的数据表。DataFrame旨在使大数据集的处理更加容易,它允许开发人员强加一个结构到分布式数据集合上,从而支持更高级别的抽象;它提供了一个领域特定语言API去操作你的分布式数据;且使得Spark面向更广泛的手中,而不仅仅是专业的数据工程师。
在Spark2.0中,DataFrame的API与Dataset的API进行了合并,统一了数据处理功能。因为这次合并,开发人员现在只需要记住更少的概念,并使用一个高级且类型安全的名为Dataset的API。


image.png

三.Datasets

从Spark 2.0开始,Dataset具有两个截然不同的API特性:一个强类型API和一个无类型API,如下表所示。
1.从概念上讲,可以将DataFrame看作是泛型对象Dataset[Row]的一个别名,其中的Row是原生无类型的JVM对象。
2.相比之下,Dataset是强类型JVM对象的集合,由Scala中定义的case类或Java中的类决定。

有类型及无类型API

image.png

四.Dataset API的优势

1.静态类型和运行时类型安全

如果将静态类型和运行时安全看作一个范围,SQL对数据集的限制最小。例如,在Spark SQL字符串查询中,直到运行时才能直到语法错误(这会很浪费时间),然而在DataFrame和Dataset中,你可以在编译时即发现错误(这节省了开发者的时间和资源)。也就是说,如果在DataFrame中调用了不属于API的函数,编译器会捕获它。然而,它直到运行时才会检测到一个不存在的列名。
限制最大的是Dataset。由于Dataset API都表示为lambda函数和JVM类型化对象,因此在编译时将检测到任何类型参数的不匹配。此外,在使用Dataset时,你的分析错误也会在编译时被检测到,从而节省开发人员的时间和成本。


image.png

2.对结构和半结构化数据的高级抽象和定制视图

DataFrame作为Dataset[Row]的集合,将结构化定制视图呈现在你的半结构化数据上。假如有一个巨大的IoT设备事件数据集,用JSON表示。由于JSON是一个半结构化的格式,它很适合将数据集用作强类型Dataset[DeviceLoTData]的集合。

{"device_id": 198164, "device_name": "sensor-pad-198164owomcJZ", "ip": "80.55.20.25", "cca2": "PL", "cca3": "POL", "cn": "Poland", "latitude": 53.080000, "longitude": 18.620000, "scale": "Celsius", "temp": 21, "humidity": 65, "battery_level": 8, "c02_level": 1408, "lcd": "red", "timestamp" :1458081226051}

你可以使用scala case类将每个JSON条目表示为DeviceIoTData,这是一个定制对象。

case class DeviceIoTData(battery_level: Long, c02_level: Long,  cca2: String, cca3: String, cn: String, device_id: Long, device_name: String, humidity: Long, ip: String, latitude: Double, lcd: String, longitude: Double, scale:String, temp: Long, timestamp: Long)

然后,我们可以从一个JSON文件中读取数据:

//read the json file and create the dataset from the
//case class DeviceIoTData
//ds is now a collection of JVM Scala objects DeviceIoTData
val ds = spark.read.json("/databricks-public-datasets/data/iot/iot_devices.json").as[DeviceIoTData]

这段代码的底层发生了三件事情:
1.Spark读取JSON文件,推断列,并创建一个DataFrame集合。
2.Spark将你的数据转换为DataFrame = Dataset[Row],一个泛型Row对象的集合,因为它不知道确切的类型。
3.现在,Spark将Dataset[Row]转换为Dataset[DeviceIoTData]这个确定类型的Scala JVM对象,因为它检测到了DeviceIoTData类。
我们大多数使用结构化数据的人都习惯于以柱状方式查看和处理数据,或者访问对象中的特定属性。使用Dataset作为Dataset[ElementType]类型化对象的集合,你可以无缝的获得强类型化JVM对象的编译时安全和自定义视图。从上面代码中得到的强类型Dataset[T]可以很容易的通过高级方法显示或处理。


image.png

3.结构化API的易用性

尽管结构可能会限制Spark程序对数据的控制,但它引入了丰富的语义和一组简单的领域特定操作。然而,大多数计算都可以通过Dataset的高级API完成。例如,通过一个Dataset来实现agg,select,sum,avg,map,filter或者groupBy操作比直接使用RDD要容易的多。
使用领域特定API表示计算要比使用关系代数类型表达式(RDD中)简单得多。例如,下面的代码将通过filter()和map()创建另一个不可变的Dataset。

//use filter(), map(), groupBy() country, and compute avg()
//for temperatures and humidity. this operation results in
//another immutable Dataset.the query is simpler to read,
//and expressive
val dsAvgTmp = ds.filter(d => {d.temp > 25}).map(d => (d.temp, d.humidity, d.cca3)).groupBy($"_3").avg()

//display the resulting dataset
display(dsAvgTmp)
image.png

4.性能和优化

除了上述提到的所有优势以外,你不能忽视DataFrame和Dataset带来的空间和性能上的收益,原因有二:
1.因为DataFrame和Dataset的API建立在Spark SQL引擎之上,它利用的Catalyst生成优化的逻辑物理执行计划。通过R,Java,Scala或Python调用DataFrame/Dataset的API,所有的关系类型查询都经历了相同的代码优化器,提供了空间和速度的优化。Dataset[T]是为数据工程任务而优化的,非类型化的Dataset[Row](DataFrame的别名)对于交互式分析具有更快,更适合的特性。


image.png

2.由于Spark作为编译器去理解你的Dataset类型 JVM对象,它使用编码器将特定类型的JVM对象映射到Tungsten的内部内存。因此,Tungsten的编码器可以高效的序列化/反序列化JVM对象,生成紧凑的字节码,这可以以更高效的速度执行。

五.什么时候该用DataFrame或者Dataset?

1.如果你想要丰富的语义、高级抽象和领域特定API,那么使用DataFrame或Dataset。
2.如果你的应用需要高级表达式,filter,map,aggregation,average,sum,SQL查询,柱状访问以及在半结构化数据上使用lambda函数,使用DataFrame或Dataset。
3.如果你想要在编译时获得更高的类型安全性,类型化的JVM对象,利用Catalyst进行优化,并从Tungsten的高效代码生成器中获益,使用Dataset。
4.如果你希望跨Spark库同一和简化API,使用DataFrame或Dataset。
5.如果你是一个R的用户,使用DataFrame。
6.如果你是一个Python用户,使用DataFrame,如果你希望更多的控制,退回使用RDD。

你可以无缝的将DataFrame和Dataset转换为RDD,通过调用.rdd.

//select specific fields from the Dataset, apply a predicate
//using the where() method, convert to an RDD, and show first 10
//RDD rows
val deviceEventsDS = ds.select($"device_name", $"cca3", $"c02_level").where($"c02_level" > 1300)
//convert to RDDs and take the first 10 rows
val eventsRDD = deviceEventsDs.rdd.take(10)
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,373评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,732评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,163评论 0 238
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,700评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,036评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,425评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,737评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,421评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,141评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,398评论 2 243
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,908评论 1 257
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,276评论 2 251
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,907评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,018评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,772评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,448评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,325评论 2 261

推荐阅读更多精彩内容