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]。
    {
"device_id": ,
"device_name": "sensor-pad-198164owomcJZ",
"ip": "80.55.20.25",
"cca2": "PL",
"cca3": "POL",
"cn": "Poland",
"latitude": 53.08,
"longitude": 18.62,
"scale": "Celsius",
"temp": ,
"humidity": ,
"battery_level": ,
"c02_level": ,
"lcd": "red",
"timestamp":
}

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

    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文件读取数据

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

  • 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:
    // 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" > )
// convert to RDDs and take the first 10 rows 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. Dom监听组合按键

    JS监听组合按键   有些时候,我们需要在网页上,增加一些快捷按键,方便用户使用一些常用的操作,比如:保存,撤销,复制.粘贴等等. 下面简单梳理一下思路: 我们所熟悉的按键有这么集中类型: 单独的按键 ...

  2. C++ 类中的静态成员变量,静态成员函数

    //类中的静态成员变量,静态成员函数 #define _CRT_SECURE_NO_WARNINGS #include<iostream> using namespace std; /* ...

  3. Nginx upstream性能优化

    1      目的 完成基于大报文和小报文场景的Nginx压测方案设计,其在长连接和短连接的最佳并发模型测试结果如下表: 大报文在短连接场景QPS在1.8K左右,在长连接场景QPS在2.1K左右,提升 ...

  4. Juicer——a fast template engine

    https://blog.csdn.net/yutao_struggle/article/details/79201688 当前最新版本: 0.6.8-stable Juicer 是一个高效.轻量的前 ...

  5. 在Hyper-V Linux VM如何选择LIS Linux集成服务

    导读 很多工程师都知道,如果你选择在 Hyper-V 中运行 Linux guest VM,要获得最好的使用体验,必需针对你所使用的 Linux 发行版和使用场景选择 Linux Integratio ...

  6. 【BZOJ4808/3175】马/[Tjoi2013]攻击装置 最小割

    [BZOJ4808]马 Description 众所周知,马后炮是中国象棋中很厉害的一招必杀技."马走日字".本来,如果在要去的方向有别的棋子挡住(俗称"蹩马腿" ...

  7. Linux下查看nginx的安装路径

    输入:nginx -V 输出:configure arguments: --prefix=/usr/local/nginx

  8. ajax请求加全局loading , 个别特殊请求不显示loading

    项目中,请求开始前加载loading遮罩层,请求结束关闭遮罩,一般都会加在全局中,但有个别请求不需要加全局loading 的话,这时候就需要对这些请求进行配置 全局加loading: ; functi ...

  9. navicat自动生成DDL语句

    场景:当我们在开发库修改表结构之后,需要把这些表结构的变化同步更新到生产库,这时候可以在Navicat中copy表结构变更的SQL语句. 当你点击了“设计表”进行修改表结构,在保存表结构之前点击“SQ ...

  10. Delphi编写下载程序:UrlDownloadToFile的进度提示

    urlmon.dll中有一个用于下载的API,MSDN中的定义如下: HRESULT URLDownloadToFile(             LPUNKNOWN pCaller,       L ...