快速理解Spark Dataset

1. 前言

RDD、DataFrame、Dataset是Spark三个最重要的概念,RDD和DataFrame两个概念出现的比较早,Dataset相对出现的较晚(1.6版本开始出现),有些开发人员对此还不熟悉,本文重点引领快速理解Dataset。

带着几个问题去阅读:
1、DataFrame比RDD有哪些优点?
2、DataFrame和Dataset有什么关系?
3、有了DataFrame为什么还有引入Dataset?
4、Dataset在Spark源码中长什么样?

注:本文的环境基于当前最新版本 Spark-2.1.1

2. RDD/DataFrame快速回顾

RDD

弹性分布式数据集,是Spark对数据进行的一种抽象,可以理解为Spark对数据的一种组织方式,更简单些说,RDD就是一种数据结构,里面包含了数据和操作数据的方法

从字面上就能看出的几个特点:

弹性:

  • 数据可完全放内存或完全放磁盘,也可部分存放在内存,部分存放在磁盘,并可以自动切换
  • RDD出错后可自动重新计算(通过血缘自动容错)
  • 可checkpoint(设置检查点,用于容错),可persist或cache(缓存)
  • 里面的数据是分片的(也叫分区,partition),分片的大小可自由设置和细粒度调整

分布式:

  • RDD中的数据可存放在多个节点上

数据集:

  • 数据的集合,没啥好说的

相对于与DataFrame和Dataset,RDD是Spark最底层的抽象,目前是开发者用的最多的,但逐步会转向DataFrame和Dataset(当然,这是Spark的发展趋势)

DataFrame

DataFrame:理解了RDD,DataFrame就容易理解些,DataFrame的思想来源于Python的pandas库,RDD是一个数据集,DataFrame在RDD的基础上加了Schema(描述数据的信息,可以认为是元数据,DataFrame曾经就有个名字叫SchemaRDD)

假设RDD中的两行数据长这样



那么DataFrame中的数据长这样


从上面两个图可以看出,DataFrame比RDD多了一个表头信息(Schema),像一张表了,DataFrame还配套了新的操作数据的方法,DataFrame API(如df.select())和SQL(select id, name from xx_table where ...)。

有了DataFrame这个高一层的抽象后,我们处理数据更加简单了,甚至可以用SQL来处理数据了,对开发者来说,易用性有了很大的提升。

不仅如此,通过DataFrame API或SQL处理数据,会自动经过Spark 优化器(Catalyst)的优化,即使你写的程序或SQL不高效,也可以运行的很快,很爽吧!

注意:DataFrame是用来处理结构化数据的

3. 步入正文,Dataset

官方解释如下(英语不好的同学随意的瞄一眼即可):
A Dataset is a distributed collection of data. Dataset is a new interface added in Spark 1.6 that provides the benefits of RDDs (strong typing, ability to use powerful lambda functions) with the benefits of Spark SQL’s optimized execution engine. A Dataset can be constructed from JVM objects and then manipulated using functional transformations (map, flatMap, filter, etc.). The Dataset API is available in Scala and Java. Python does not have the support for the Dataset API. But due to Python’s dynamic nature, many of the benefits of the Dataset API are already available (i.e. you can access the field of a row by name naturally row.columnName). The case for R is similar.

相对于RDD,Dataset提供了强类型支持,也是在RDD的每行数据加了类型约束

假设RDD中的两行数据长这样

那么Dataset中的数据长这样

或者长这样(每行数据是个Object)

使用Dataset API的程序,会经过Spark SQL的优化器进行优化(优化器叫什么还记得吗?)

目前仅支持Scala、Java API,尚未提供Python的API(所以一定要学习Scala)

相比DataFrame,Dataset提供了编译时类型检查,对于分布式程序来讲,提交一次作业太费劲了(要编译、打包、上传、运行),到提交到集群运行时才发现错误,实在是想骂人,这也是引入Dataset的一个重要原因。

使用DataFrame的代码中json文件中并没有score字段,但是能编译通过,但是运行时会报异常!如下图代码所示

而使用Dataset实现,会在IDE中就报错,出错提前到了编译之前

RDD转换DataFrame后不可逆,但RDD转换Dataset是可逆的(这也是Dataset产生的原因)。如下操作所示:

  • 启动spark-shell,创建一个RDD


  • 通过RDD创建DataFrame,再通过DataFrame转换成RDD,发现RDD的类型变成了Row类型

  • 通过RDD创建Dataset,再通过Dataset转换为RDD,发现RDD还是原始类型

4. Dataset基本操作

将Spark安装目录的LICENSE文件上传至HDFS上,将文件读入Spark,使用as[]转换为DataSet

使用Dataset API做转换操作

创建临时视图,进行SQL操作

使用SQL进行单词统计

使用SQL进行排名分析

5. Dataset源码初探

如果不想本地搭建源码阅读环境,推荐一款在线阅读源码的工具insight,不需要本地环境,可以直接引用github中的代码,非常方便.

Dataset的源码位于sql目录下:
sql/core/src/main/scala/org/apache/spark/sql/Dataset.scala
由此可以看出Dataset是Spark SQL组件中的东西,另外DataFrame也是SparkSQL中的东西(这也是为什么Spark SQL是Spark生态中发展最迅猛的模块)

上图显示了Dataset文件的结构,可以看出:

  1. Dataset是个类和一个伴生对象
  • 里面包含了一些变量,比如我们常用的sqlContext
  • 里面有很多函数和算子,比如toDF、map等操作数据的算子

前面我们说了,Dataset是个组织数据的的结构,那么数据存储在哪里呢?

  1. Dataset定义在sql这个包中
  • 主构造函数中需要传递三个参数
    sparkSession:运行环境信息
    queryExecution:数据和执行逻辑信息。注意,数据在这个参数中
    encoder:编码器,用于将JVM对象转换为SparkSQL的对象(当然这里会有序列化和Schema等)

我们可以使用createDataset函数来创建一个Dataset,如上图所示。
调用这个函数时,究竟发生了什么呢?

我们来看这个函数的实现:

  1. 将数据传进来后,提取数据的类型,通过类型提取Schema,并将数据转换成SparkSQL内部的Row(InternalRow)
  2. 将数据和数据属性信息封装成一个relation对象
  3. 用Dataset的伴生对象创建Dataset实例,这里的self就是SparkSession对象
  4. Dataset伴生对象中的apply方法来new Dataset生成对象,如下图所示

第三个参数没传,使用了隐式的encoder(createDataset中的encoded变量取名不规范,容易混淆)

一张简单的图,总结了创建Dataset两个最重要的步骤

到此为止我们在源码级别粗略的看了Dataset和创建流程,主要是帮助理解Dataset的概念,更多技术细节不适合本文描述。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,482评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,377评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,762评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,273评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,289评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,046评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,351评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,988评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,476评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,948评论 2 324
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,064评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,712评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,261评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,264评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,486评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,511评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,802评论 2 345

推荐阅读更多精彩内容