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. HTML5关于上传API的一些使用(中)

    上一次写了关于HTML的上传API,XMLHttpRequest2.0的上传方式,以及HTML5中上传之前本地的预览,包括对于图片以及部分信息的预 览.这次我们就讲下HTML5中关于上传的一些各种个性 ...

  2. android 百度地图开发实例(转载)

    因为在我的寝室google基站定位返回的数据总是为空,所以换成百度地图,发现百度地图开发起来非常方便,提供了许多有用的工具,地图的加载速度也比google地图快许多. 为了加强记忆,写一点androi ...

  3. The Properties of Posterior of Topic Model

    1.Tang, Jian, et al. "Understanding the Limiting Factors of Topic Modeling via Posterior Contra ...

  4. JAVA 并发编程-多个线程之间共享数据(六)

    多线程共享数据的方式: 1.假设每一个线程运行的代码同样.能够使用同一个Runnable对象,这个Runnable对象中有那个共享数据,比如,卖票系统就能够这么做. 2,假设每一个线程运行的代码不同. ...

  5. 大圣画廊v0.2(2015.7.17)

    0.2版本号加入的功能 以tag分类图片 美化.添加瀑布流效果 添加tag页和单张图片页 添加公布图片页 以下是具体解释. 每添加一个功能,都要从模型.模板,视图,路由四个方面一一改动. 模型:添加t ...

  6. windows环境通过cmd命令到ftp上下载文件到linux服务器

    转自:http://jingyan.baidu.com/article/6525d4b1300912ac7d2e941b.html

  7. 第一次广搜!HDU1548--A Strange Lift

    一上来看见题目就用了深搜(因为只会深搜)果断内存超限(据说时间也会超限)无奈只好开始用广搜 其实广搜的思路和深搜有很多类似的地方 不过实现的过程中用到了队列 因此有点难以理解(好吧我个人认为) 这题是 ...

  8. 在JavaWeb项目中处理静态文件或动态链接拼接网站地址的最优处理方案

    在开发网站时候我们会遇到下面问题? - 在引用网页中引用js和css或者动态的Servlet的时候我们是写绝对路径还是相对路径? - 如果写相对路径吧,上线偶尔会报404,还要手动去拼接绝对路径 - ...

  9. Python--上传文件和下载文件

    #!/usr/bin/env python# -*- coding: utf-8 -*-# @Time : 2017/12/28 13:56# @Author : Aries# @Site : # @ ...

  10. 1. Action 实现 ModelDriven 接口后的运行流程

    1). 先会执行 ModelDrivenInterceptor 的 intercept 方法. public String intercept(ActionInvocation invocation) ...