Apache Spark吸引广大社区开发者的一个重要原因是:Apache Spark提供极其简单、易用的APIs,支持跨多种语言(比如:Scala、Java、Python和R)来操作大数据。

本文主要讲解Apache Spark 2.0中RDD,DataFrame和Dataset三种API;它们各自适合的使用场景;它们的性能和优化;列举使用DataFrame和DataSet代替RDD的场景。文章大部分聚焦DataFrame和Dataset,因为这是Apache Spark 2.0的API统一的重点。

Apache Spark 2.0统一API的主要动机是:追求简化Spark。通过减少用户学习的概念和提供结构化的数据进行处理。除了结构化,Spark也提供higher-level抽象和API作为特定领域语言(DSL)。

弹性数据集(RDD)

RDD是Spark建立之初的核心API。RDD是不可变分布式弹性数据集,在Spark集群中可跨节点分区,并提供分布式low-level API来操作RDD,包括transformation和action。

那什么时候用RDD呢?

使用RDD的一般场景:

  • 你需要使用low-level的transformation和action来控制你的数据集;
  • 你的数据集非结构化,比如:流媒体或者文本流;
  • 你想使用函数式编程来操作你的数据,而不是用特定领域语言(DSL)表达;
  • 你不在乎schema,比如,当通过名字或者列处理(或访问)数据属性不在意列式存储格式;
  • 你放弃使用DataFrame和Dataset来优化结构化和半结构化数据集。

RDD在Apache Spark 2.0中惨遭抛弃?

你可能会问:RDD是不是成为“二等公民”了?或者是不是干脆以后不用了?
答案当然是NO!
通过后面的描述你会得知:Spark用户可以在RDD,DataFrame和Dataset三种数据集之间无缝转换,而且只需要使用超级简单的API方法。

DataFrame

DataFrame与RDD相同之处,都是不可变分布式弹性数据集。不同之处在于,DataFrame的数据集都是按指定列存储,即结构化数据。类似于传统数据库中的表。DataFrame的设计是为了让大数据处理起来更容易。DataFrame允许开发者把结构化数据集导入DataFrame,并做了higher-level的抽象;DataFrame提供特定领域的语言(DSL)API来操作你的数据集。
在Spark2.0中,DataFrame API将会和Dataset  API合并,统一数据处理API。由于这个统一“有点急”,导致大部分Spark开发者对Dataset的high-level和type-safe API并没有什么概念。

Dataset

在Spark
2.0中,Dataset具有两个完全不同的API特征:强类型API和弱类型API,见下表。DataFrame是特殊的Dataset,其每行是一个弱类型JVM
object。相对应地,Dataset是强类型JVM object的集合,通过Scala的case class或者Java class。
强类型API和弱类型API
Language Main Abstraction
Scala Dataset[T] & DataFrame (alias for Dataset[Row])
Java Dataset<T>
Python* DataFrame
R* DataFrame

Note:Python和R没有编译时type-safety,所以只提供弱类型的API:DataFrame。

Dataset API的优势

对于Spark开发者而言,你将从Spark 2.0的DataFrame和Dataset统一的API获得以下好处:
1. 静态类型和运行时类型安全
考虑静态类型和运行时类型安全,SQL有很少的限制而Dataset限制很多。例如,Spark
SQL查询语句,你直到运行时才能发现语法错误(syntax
error),代价较大。然后DataFrame和Dataset在编译时就可捕捉到错误,节约开发时间和成本。
Dataset API都是lambda函数和JVM typed object,任何typed-parameters不匹配即会在编译阶段报错。因此使用Dataset节约开发时间。

2. High-level抽象以及结构化和半结构化数据集的自定义视图

DataFrame是Dataset[Row]的特例,把结构化数据集视图用于半结构化数据集。例如,有个海量IoT设备事件数据集,用JSON格式表示。JSON是一个半结构化数据格式,这里可以自定义一个Dataset:Dataset[DeviceIoTData]。
  1. {
  2. "device_id": ,
  3. "device_name": "sensor-pad-198164owomcJZ",
  4. "ip": "80.55.20.25",
  5. "cca2": "PL",
  6. "cca3": "POL",
  7. "cn": "Poland",
  8. "latitude": 53.08,
  9. "longitude": 18.62,
  10. "scale": "Celsius",
  11. "temp": ,
  12. "humidity": ,
  13. "battery_level": ,
  14. "c02_level": ,
  15. "lcd": "red",
  16. "timestamp":
  17. }

用Scala为JSON数据DeviceIoTData定义case class。

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

紧接着,从JSON文件读取数据

这个时候有三个事情会发生:

  • Spark读取JSON文件,推断出其schema,创建一个DataFrame;
  • Spark把数据集转换DataFrame -> Dataset[Row],泛型Row object,因为这时还不知道其确切类型;
  • Spark进行转换:Dataset[Row] -> Dataset[DeviceIoTData],DeviceIoTData类的Scala JVM object。
3. 简单易用的API
虽然结构化数据会给Spark程序操作数据集带来挺多限制,但它却引进了丰富的语义和易用的特定领域语言。大部分计算可以被Dataset的high-level API所支持。例如,简单的操作agg,select,avg,map,filter或者groupBy即可访问DeviceIoTData类型的Dataset。
使用特定领域语言API进行计算是非常简单的。例如,使用filter()和map()创建另一个Dataset。

4. 性能和优化

使用DataFrame和Dataset API获得空间效率和性能优化的两个原因:

首先,DataFrame和Dataset API是建立在Spark SQL引擎之上,它会使用Catalyst优化器来生成优化过的逻辑计划和物理查询计划。R,Java,Scala或者Python的DataFrame/Dataset API使得查询都进行相同的代码优化以及空间和速度的效率提升。

其次,Spark作为编译器可以理解Dataset类型的JVM object,它能映射特定类型的JVM
object到Tungsten内存管理,使用Encoder。Tungsten的Encoder可以有效的序列化/反序列化JVM
object,生成字节码来提高执行速度。

什么时候使用DataFrame或者Dataset?

  • 你想使用丰富的语义,high-level抽象,和特定领域语言API,那你可以使用DataFrame或者Dataset;
  • 你处理的半结构化数据集需要high-level表达,filter,map,aggregation,average,sum,SQL查询,列式访问和使用lambda函数,那你可以使用DataFrame或者Dataset;
  • 你想利用编译时高度的type-safety,Catalyst优化和Tungsten的code生成,那你可以使用DataFrame或者Dataset;
  • 你想统一和简化API使用跨Spark的Library,那你可以使用DataFrame或者Dataset;
  • 如果你是一个R使用者,那你可以使用DataFrame或者Dataset;
  • 如果你是一个Python使用者,那你可以使用DataFrame或者Dataset。
你可以无缝地把DataFrame或者Dataset转化成一个RDD,只需简单的调用.rdd:
  1. // select specific fields from the Dataset, apply a predicate
  2. // using the where() method, convert to an RDD, and show first 10
  3. // RDD rows
  4.  
  5. val deviceEventsDS = ds.select($"device_name", $"cca3", $"c02_level").where($"c02_level" > )
  6. // convert to RDDs and take the first 10 rows
  7.  
  8. val eventsRDD = deviceEventsDS.rdd.take()

总结

通过上面的分析,什么情况选择RDD,DataFrame还是Dataset已经很明显了。RDD适合需要low-level函数式编程和操作数据集的情况;DataFrame和Dataset适合结构化数据集,使用high-level和特定领域语言(DSL)编程,空间效率高和速度快。

Apache Spark 2.0三种API的传说:RDD、DataFrame和Dataset的更多相关文章

  1. Apache Spark探秘:三种分布式部署方式比较

    转自:链接地址: http://dongxicheng.org/framework-on-yarn/apache-spark-comparing-three-deploying-ways/     目 ...

  2. 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 ...

  3. Apache Spark 3.0 将内置支持 GPU 调度

    如今大数据和机器学习已经有了很大的结合,在机器学习里面,因为计算迭代的时间可能会很长,开发人员一般会选择使用 GPU.FPGA 或 TPU 来加速计算.在 Apache Hadoop 3.1 版本里面 ...

  4. Apache Spark 3.0 预览版正式发布,多项重大功能发布

    2019年11月08日 数砖的 Xingbo Jiang 大佬给社区发了一封邮件,宣布 Apache Spark 3.0 预览版正式发布,这个版本主要是为了对即将发布的 Apache Spark 3. ...

  5. Navisworks 提供了.NET, COM和NwCreate 三种API

    Navisworks 提供了.NET, COM和NwCreate 三种API.而通常我们说Navisworks API其实指的只是COM或.NET,因为NwCreate的功能比较特殊.待我一一道来: ...

  6. 【转】Apache 配置虚拟主机三种方式

    Apache 配置虚拟主机三种方式  原文博客http://www.cnblogs.com/hi-bazinga/archive/2012/04/23/2466605.html 一.基于IP 1. 假 ...

  7. Aurora 8B/10B、PCIe 2.0、SRIO 2.0三种协议比较

    在高性能雷达信号处理机研制中,高速串行总线正逐步取代并行总线.业界广泛使用的Xilinx公司Virtex-6系列FPGA支持多种高速串行通信协议,本文针对其中较为常用的Aurora 8B/10B和PC ...

  8. Spark学习笔记-三种属性配置详细说明【转】

    相关资料:Spark属性配置  http://www.cnblogs.com/chengxin1982/p/4023111.html 本文出处:转载自过往记忆(http://www.iteblog.c ...

  9. Tomcat、Apache、IIS这三种Web服务器来讲述3种搭建JSP运行环境的方法

    一.相关软件介绍 1. J2SDK:Java2的软件开发工具,是Java应用程序的基础.JSP是基于Java技术的,所以配置JSP环境之前必须要安装J2SDK. 2. Apache服务器:Apache ...

随机推荐

  1. [插件] 如何在一个页面中使用多个SWFUpload对象上传文件

    首先需要引入相应的样式和JS文件,还需要借助jQuery的js 提供下载路径:http://pan.baidu.com/s/1EUzca ① 引入js <script type="te ...

  2. 关于Unity的游戏的运行模式

    游戏有个入口main函数,执行完main函数就返回 main函数中的步骤 1.初始化 2.while(true){ a.检查有没有消息,包括鼠标有没有被点击,键盘有没有被点击,自定义事件等等,有消息就 ...

  3. Differential Geometry之第八章常Gauss曲率曲面

    第八章.常Gauss曲率曲面 1.常正Gauss曲率曲面 2.常负Gauss曲率曲面与Sine-Gordon方程 3.Hilbert定理 4.Backlund变换 4.1.线汇与焦曲面 4.2.Bac ...

  4. 第二百七十一节,Tornado框架-CSRF防止跨站post请求伪造

    Tornado框架-CSRF防止跨站post请求伪造 CSRF是什么 CSRF是用来在post请求时做请求验证的,防止跨站post请求伪造 当用户访问一个表单页面时,会自动在表单添加一个隐藏的inpu ...

  5. 【BZOJ】1626: [Usaco2007 Dec]Building Roads 修建道路(kruskal)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1626 依旧是水题..太水了.. #include <cstdio> #include & ...

  6. linux系统命令记录

    系统 # uname -a # 查看内核/操作系统/CPU信息 # head -n 1 /etc/issue # 查看操作系统版本 # cat /proc/cpuinfo # 查看CPU信息 # ho ...

  7. 【mysql】windows7 安装 Mysql

    From: http://jingyan.baidu.com/article/e52e3615a1128c40c70c5174.html 安装(解压) ZIP Archive版是免安装的.只要解压就行 ...

  8. print多重打印

    遇见有趣的问题必须记录下来,当时的想法思路也要记下来 以下两行代码打印出来的结果会是什么 print('2 * 3 = %d' % (2 * 3)) print('2 * 3 = %d' % 2 * ...

  9. 灵活的javaScript

    通常我们不像下面这样声明函数,因为会创建很多全局变量. function checkName() { // code } function checkEmail() { // code } 所以,我们 ...

  10. Libcap的简介及安装

    Libpcap 简介 libpcap 是unix/linux 平台下的网络数据包捕获函数包, 大多数网络监控软件都以它为基础. Libpcap 可以在绝大多数类unix 平台下工作. Libpcap  ...