Spark最吸引开发者的就是简单易用、跨语言(Scala, Java, Python, and R)的API。

本文主要讲解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来优化结构化和半结构化数据集的时候。

在Spark2.0中RDD发生了什么

你可能会问:RDD是不是成为“二等公民”了?或者是不是干脆以后不用了?

答案当然是NO!

通过后面的描述你会得知:Spark用户可以在RDD,DataFrame和Dataset三种数据集之间无缝转换,而且只需要使用超级简单的API方法。

DataFrames

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并没有什么概念。

DataSets

从Spark2.0开始,DataSets扮演了两种不同的角色:强类型API和弱类型API,见下表。从概念上来讲,可以把DataFrame 当作一个泛型对象的集合DataSet[Row], Row是一个弱类型JVM 对象。相对应地,如果JVM对象是通过Scala的case class或者Java class来表示的,Dataset是强类型的。

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]。

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

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

上面代码运行时底层会发生下面3件事。

Spark读取JSON文件,推断出其schema,创建一个DataFrame;

Spark把数据集转换DataFrame -> Dataset[Row],泛型Row object,因为这时还不知道其确切类型;

Spark进行转换:Dataset[Row] -> Dataset[DeviceIoTData],DeviceIoTData类的Scala JVM object

我们的大多数人,在操作结构化数据时,都习惯于以列的方式查看和处理数据列,或者访问对象的指定列。Dataset 是Dataset[ElementType]类型对象的集合,既可以编译时类型安全,也可以为强类型的JVM对象定义视图。从上面代码获取到的数据可以很简单的展示出来,或者用高层方法处理。

3. 简单易用的API

虽然结构化数据会给Spark程序操作数据集带来挺多限制,但它却引进了丰富的语义和易用的特定领域语言。大部分计算可以被Dataset的high-level API所支持。例如,简单的操作agg,select,avg,map,filter或者groupBy即可访问DeviceIoTData类型的Dataset。

使用特定领域语言API进行计算是非常简单的。例如,使用filter()和map()创建另一个Dataset。

把计算过程翻译成领域API比RDD的关系代数式表达式要容易的多。例如:

4. 性能和优化

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

首先:因为DataFrame和Dataset是在Spark SQL 引擎上构建的,它会使用Catalyst优化器来生成优化过的逻辑计划和物理查询计划。

R,Java,Scala或者Python的DataFrame/Dataset API,所有的关系型的查询都运行在相同的代码优化器下,代码优化器带来的的是空间和速度的提升。不同的是Dataset[T]强类型API优化数据引擎任务,而弱类型API DataFrame在交互式分析场景上更快,更合适。

其次,通过博客https://databricks.com/blog/2016/05/23/apache-spark-as-a-compiler-joining-a-billion-rows-per-second-on-a-laptop.html 可以知道:Dataset能使用Encoder映射特定类型的JVM 对象到Tungsten内部内存表示。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:

总结

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

Spark(十六)DataSet的更多相关文章

  1. Spark(十六)【SparkStreaming基本使用】

    目录 一. SparkStreaming简介 1. 相关术语 2. SparkStreaming概念 3. SparkStreaming架构 4. 背压机制 二. Dstream入门 1. WordC ...

  2. 十六款值得关注的NoSQL与NewSQL数据库--转载

    原文地址:http://tech.it168.com/a2014/0929/1670/000001670840_all.shtml [IT168 评论]传统关系型数据库在诞生之时并未考虑到如今如火如荼 ...

  3. ASP.NET Core 2.2 : 十六.扒一扒新的Endpoint路由方案 try.dot.net 的正确使用姿势 .Net NPOI 根据excel模板导出excel、直接生成excel .Net NPOI 上传excel文件、提交后台获取excel里的数据

    ASP.NET Core 2.2 : 十六.扒一扒新的Endpoint路由方案   ASP.NET Core 从2.2版本开始,采用了一个新的名为Endpoint的路由方案,与原来的方案在使用上差别不 ...

  4. Alink漫谈(十六) :Word2Vec源码分析 之 建立霍夫曼树

    Alink漫谈(十六) :Word2Vec源码分析 之 建立霍夫曼树 目录 Alink漫谈(十六) :Word2Vec源码分析 之 建立霍夫曼树 0x00 摘要 0x01 背景概念 1.1 词向量基础 ...

  5. 我的MYSQL学习心得(十六) 优化

    我的MYSQL学习心得(十六) 优化 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据 ...

  6. Bootstrap <基础二十六>进度条

    Bootstrap 进度条.在本教程中,你将看到如何使用 Bootstrap 创建加载.重定向或动作状态的进度条. Bootstrap 进度条使用 CSS3 过渡和动画来获得该效果.Internet ...

  7. Bootstrap<基础十六> 导航元素

    Bootstrap 提供的用于定义导航元素的一些选项.它们使用相同的标记和基类 .nav.Bootstrap 也提供了一个用于共享标记和状态的帮助器类.改变修饰的 class,可以在不同的样式间进行切 ...

  8. 解剖SQLSERVER 第十六篇 OrcaMDF RawDatabase --MDF文件的瑞士军刀(译)

    解剖SQLSERVER 第十六篇 OrcaMDF RawDatabase --MDF文件的瑞士军刀(译) http://improve.dk/orcamdf-rawdatabase-a-swiss-a ...

  9. Senparc.Weixin.MP SDK 微信公众平台开发教程(十六):AccessToken自动管理机制

    在<Senparc.Weixin.MP SDK 微信公众平台开发教程(八):通用接口说明>中,我介绍了获取AccessToken(通用接口)的方法. 在实际的开发过程中,所有的高级接口都需 ...

随机推荐

  1. random函数详解

    1. 随机函数  Math.random() Math.random();    取值范围是  [ 0.0,1.0 )  的左闭右开区间.具体源代码如下所示:   Math.random()是生成0~ ...

  2. 《剑指offer》面试题32----从1到n整数中1出现的次数

    题目:输入一个整数n,求从1到n这n个整数的十进制表示中1出现的次数.例如输入12,从1到12这些整数中包含1的数字有1,10,11和12,1一共出现了5次. 解法一:不考虑时间效率的解法(略) ps ...

  3. 视音频数据处理入门:PCM音频采样数据处理

    ===================================================== 视音频数据处理入门系列文章: 视音频数据处理入门:RGB.YUV像素数据处理 视音频数据处理 ...

  4. webapi框架搭建-安全机制(四)-可配置的基于角色的权限控制

    webapi框架搭建系列博客 在上一篇的webapi框架搭建-安全机制(三)-简单的基于角色的权限控制,某个角色拥有哪些接口的权限是用硬编码的方式写在接口上的,如RBAuthorize(Roles = ...

  5. spring框架学习(六)AOP事务及spring管理事务方式之Template模板

    概念 1.事务 1)事务特性:ACID 原子性 :强调事务的不可分割. 一致性 :事务的执行的前后数据的完整性保持一致. 隔离性 :一个事务执行的过程中,不应该受到其他事务的干扰. 持久性 :事务一旦 ...

  6. spring-boot Test for Controller

    spring-boot  controller 测试示例: 单元测试类 package com.zzhi; import com.fasterxml.jackson.databind.ObjectMa ...

  7. 利用XMLHttpRequest(XHR)对象实现与web服务器通信

    XMLHttpRequest对象:XMLHttpRequest是一个JS对象,页面利用它与web服务器通信.XHR对象的基本思想是让JS代码自己发送请求,以便随时获取数据,这种请求是异步的,也就是说请 ...

  8. IT人应当知道的10个行业小内幕

    如果你打算从事IT行业或刚进入这个行业,也许本文下面的小内幕会吓到你,因为这些事平常都不会公开讨论的.如果你是IT资深人士,或许你已经遇到其中的大部分了.如果你愿意,请一起来参与讨论吧. 这些内幕大多 ...

  9. TreeSet按value排序

    今天学习到TreeSet,但是它是按照key的值来排序的,那如果我们想要按照value的值排序呢?这个问题我上网看了好久,终于找到一个比较易懂的例子: 例:(统计输入数字的个数) 话不多说,看代码就懂 ...

  10. Druid.io启用SQL支持

    Druid.io的SQL功能虽然在试验阶段,但是也支持了大部分的功能,而且还可以通过 Avatica JDBC查看请求的json,有助于我们理解Druid.io的语法.Druid.io有个比较坑的是, ...