Spark2 Dataset实现原理分析-Dataset实现原理概要

概述

本文讲述spark sql中的dataset的组成部分,并对其创建过程进行分析。

Dataset要点

我们可以总结出dataset的一些要点,如下:

  • 和关系型数据表一样,Dataset是强类型的。
  • 数据集的行的集合,被称为Dataframe。
  • 和RDD一样,Dataset的操作分为两类:转换(transformations)和行动(action)。
  • 和RDD一样,Dataset是lazy的,也就是说当执行action函数时才会执行计算任务。
  • 一个Dataset表示一个逻辑计划(logic plan),用来描述产生数据该如何计算。
  • 当执行Dataset的action函数时,会对logic plan进行优化,从而形成物理计划(physical plan)。
  • 可以通过Dataset的explain函数来查看逻辑计划和物理计划。
  • 为了更加有效的支持某个特定域的对象,Dataset使用了编码器(Encoder)。
  • Encoder会将特定的域类型映射到Spark的内部类型。这样可以减少内存的使用率和提升数据处理的效率。

Dataset介绍

数据集(Dataset)是具有强类型的某个特定域的对象的集合,该集合可以使用函数或关系运算并行转换(transformed)。 每个数据集还有一个称为“DataFrame”的无类型视图,它是数据集行([Row])的集合。

和RDD一样,基于数据集的操作可以分为转换(transformations)和行动(action)。transformations操作会产生新的数据集(可能有多种不同类型),action操作会触发计算任务并返回结果。

transformations包括:map,filter,select和aggregate(groupBy)。
action包括:count, show或写入文件系统。

数据集是"懒惰的"(lazy),即只有在调用action的函数时才会触发计算。在数据集的内部实现层面,一个数据集表示一个逻辑计划(logic plan),该逻辑计划描述产生数据该如何计算。

当调用action操作函数时,Spark的查询优化器(query optimizer)会优化逻辑计划,并按并行(parallel)和分布式(distributed)的方式生成有效执行的物理计划(physical plan)。可以通过explain函数来探查逻辑计划和优化的物理计划。

为了更加有效的支持某个特域的对象,需要使用编码器([Encoder])。编码器将域特定类型T映射到Spark的内部类型系统。例如,给定一个带有两个字段的Personname(string)和age(int),编码器用于告诉Spark在运行时生成代码以将Person对象序列化为二进制结构。该二进制结构通常占用更少的内存和对数据处理(例如,柱状格式)的效率进行优化。要了解数据的内部二进制表示,可以使用schema函数。

注意:以上文字基本上都来自于Dataset类的实现代码注释。

Dataset的组成

Dataset实现的组成如下图所示:
Spark2 Dataset实现原理分析-Dataset实现原理概要_第1张图片

dataset的action执行过程概要

dataset的大致执行过程如下图所示:
Spark2 Dataset实现原理分析-Dataset实现原理概要_第2张图片
注意,该图是dataset执行的一个概要,其中省略了一些比较细节的环节。

可见,dataset的执行过程大体分为三个大的阶段,一个是逻辑执行计划(logic plan)的创建和分析及其优化阶段,一个是物理执行计划(physical plan)的创建和优化,最后一个是形成rdd和并执行任务的阶段。从图中可以大体看出这几个阶段。

打印Dataset的逻辑执行计划(logic plan)

通过对dataset的queryExecution参数,我们可以打印出dataset的逻辑执行计划,如下:

scala> dada.sort(col("_c0")).queryExecution
res4: org.apache.spark.sql.execution.QueryExecution =
== Parsed Logical Plan ==
'Sort ['_c0 ASC NULLS FIRST], true
+- Relation[_c0#12,_c1#13,_c2#14,_c3#15,_c4#16] csv

== Analyzed Logical Plan ==
_c0: string, _c1: string, _c2: string, _c3: string, _c4: string
Sort [_c0#12 ASC NULLS FIRST], true
+- Relation[_c0#12,_c1#13,_c2#14,_c3#15,_c4#16] csv

== Optimized Logical Plan ==
Sort [_c0#12 ASC NULLS FIRST], true
+- Relation[_c0#12,_c1#13,_c2#14,_c3#15,_c4#16] csv

== Physical Plan ==
*Sort [_c0#12 ASC NULLS FIRST], true, 0
+- Exchange rangepartitioning(_c0#12 ASC NULLS FIRST, 200)
   +- *FileScan csv [_c0#12,_c1#13,_c2#14,_c3#15,_c4#16] Batched: false, Format: CSV, Location: InMemoryFileIndex[hdfs://localhost:9000/curdata/idtimedata], PartitionFilters: [], PushedFilters: [], ReadSchema: s...

说明:其中的_c0是加载的数据没有Header而产生的列名。

另外,也可以通过explain函数,来打印逻辑和物理执行计划。

总结

本文讲述了spark dataset的实现原理的概要。并介绍了dataset的操作实现的大致流程。

你可能感兴趣的:(spark,大数据处理,深入浅出Spark原理)