《Spark -- The Definitive Guide》学习笔记Note.4

  这一期开始,我们将要深入讨论Spark的结构化API,主要有DataFrame,SQL,Dataset,分享过程中若有错谬,欢迎拍砖。

Part 2.Structured APIs——DataFrames,SQL,and Datasets

Charpter 4.Structured API Overview

  这一部分将深入探讨Spark的结构化API。结构化API是处理各种数据类型的工具,从非结构化的日志文件,到半结构化的CSV文件,再到高度结构化的Parquet文件。结构化API一般指如下三种核心的分布式集合类型的API:

  1. Dataset
  2. DataFrames
  3. SQL表和视图

  这三种类型在本书的不同部分有所介绍,大多数结构化API均适用于批处理和流处理,这意味着使用结构化API编写代码时,很容易可以在批处理和流处理程序之间相互转换。
  结构化API是在编写大部分数据流时会用到的基础抽象概念。在本章中,首先介绍一些需要理解的基本概念:类型化和非类型化的API,及它们的区别;核心术语是什么; Spark如何将结构化API数据流实际应用,并在集群上执行它。然后,我们将提供具体的任务信息来处理某些类型的数据或数据源。
  我们先回顾一下第一篇分享中介绍的基本概念和定义。 Spark是一个分布式编程模型,用户可以在其中指定转换操作,多次转换操作会建立起指令的DAG(direct acyclic graph)(有向无环图)。指令图的执行过程中,由一个action操作触发,期间一个作业会被分解为多个stage和task,在集群上执行transformation和action操作的逻辑结构是DataFrame和Dataset,每执行一次transformation会都会创建一个新的DataFrame或Dataset,每一次action则会触发计算,或者将DataFrame和Dataset转换成本地语言类型。

DataFrames and Datasets

  按第一期分享所介绍,Spark有两种结构化集合类型:DataFrame和Dataset。接下来我们先了解它们各自的定义,再介绍它们间细小差别。
  DataFrame和Dataset具有明确的行和列,类似于分布式数据表的集合。所有列的行数相同(可用null指定缺省值),某列的类型必须和表中的所有行保持一致。 Spark中的DataFrame和Dataset是不可变的数据集合,可以通过它对表中特定行列进行操作,操作将以惰性方式执行。当在DataFrame上执行action时,将触发Spark执行具体的transformation操作并返回结果,这些代表了如何操纵行和列来计算出用户期望结果的执行计划。
  表和视图与DataFrame基本相同,所以我们通常在DataFrame上执行SQL操作,而不是用DataFrame专用的执行代码。为了使这些定义更具体,需要先讨论一下Schema数据模式, Schema数据模式定义了该分布式集合中存储的数据类型。

Schemas

  Schema定义了DataFrame的列名和类型,可以手动定义或者从数据源读取schema(通常叫做schema on read)。 Schema由类型组成,意味着你需要指定数据列的类型和列的位置顺序。

Overview of Structured Spark Types

  Spark实际上有它自己的编程语言, Spark内部使用一个名为Catalyst的引擎,在计划制定和执行作业的过程中维护自身的类型信息,这会带来很大的优化空间,显著提高性能。 Spark类型直接映射到不同语言API,包括Scala、Java、Python、SQL和R语言,都有一个对应的API查找表。比如,下面例子中,不会在Scala或Python中执行加法,实际上仅在Spark中执行加法。

  这是因为Spark会将用输入语言编写的表达式转换为相同功能的Spark内部Catalyst表示。然后,它将在内部表示中运行。在讨论为什么会出现这种情况之前,我们先来讨论Dataset。

DataFrames versus Datasets

  结构化API包含两类API,即无类型的DataFrame和有类型的Dataset。说DataFrame是无类型可能不太准确,因为它们其实是有类型的,只是Spark完全负责维护它们的类型,仅在运行时检查这些类型是否与schema中指定的类型一致。与之相对应的, Dataset在编译时就会检查类型是否符合规范。 Dataset仅适用于基于JVM的语言(如Scala和Java),并通过case类或Java beans指定类型。
  大多情况下,你可能会用到DataFrame。在Scala版本的Spark中,DataFrame就是一些Row类型的Dataset集合。“Row”类型是Spark的内部表示形式,用于内存格式的计算优化。这种格式让计算更高效,因为如果使用JVM的类型,会带来巨大的垃圾回收和对象实例化成本,而Spark可以基于自己的内部格式运行,不会产生这种开销。对于Python或R语言版本的Spark,没有Dataset,一切都是DataFrame,这样我们就能用这种优化的数据格式进行计算处理。
  内部Catalyst格式在很多Spark演示中都有详细介绍。充分理解DataFrame,Spark类型,Schema,是要一些时间的,需要强调的是,当用户使用DataFrame时,会大大受益于这种优化过的Spark内部格式。接下来,介绍一些相对来说更熟悉的概念:列和行。

Columns

  列可以表示一个简单类型,如整数,字符串,也可以表达一个复杂类型,如数组,map映射,也可以表示空值null。Spark可以记录所有这些类型信息,并提供多种方法来转换列。后面将对列类型进行更广泛的讨论,简单来说,可以将Spark列想象为一个数据表的列。

Rows

  一行对应一个数据记录。DataFrame中的每条记录都必须是Row类型。我们可以通过SQL手动创建,也可以从RDD,从数据源,或从头创建这些行。下面我们用range()来创建一个row对象的数组。

Spark Types

  之前我们提到Spark内部有大量内部类型表示。接下来将提供一些方便查阅的参考表,它标示了在用户语言和Spark类型的对应关系。在看到参考表之前,让我们看看如何声明和实例化一个属于某种类型的列。

  

  原文依次列举了Python,Scala,Java语言的对比图,为避免文章过于冗长,这里先展示scala,有其它语言需求可以去原书查阅比较。


Table 4-2. Scala type reference

Data typeValue type in ScalaAPI to access or create a data type
ByteTypeByteByteType
ShortTypeShortShortType
IntegerTypeIntIntegerType
LongTypeLongLongType
FloatTypeFloatFloatType
DoubleTypeDoubleDoubleType
DecimalTypejava.math.BigDecimalDecimalType
StringTypeStringStringType
BinaryTypeArray[Byte]BinaryType
BooleanTypeBooleanBooleanType
TimestampTypejava.sql.TimestampTimestampType
DateTypejava.sql.DateDateType
ArrayTypescala.collection.SeqArrayType(elementType, [containsNull]) containsNull默认为true
MapTypescala.collection.MapMapType(keyType, valueType, [valueContainsNull]) valueContainsNull默认为true
StructTypeorg.apache.spark.sql.RowStructType(fields) fields是包含StructFields的Array,不允许使用同名fields
StructFieldScala中的数据类型的值类型,如Int是数据类型IntegerType的StructFieldStructField(name, dataType, [nullable]),nullable的默认值为true

  类型会随着Spark SQL版本更新而变化,建议参考最新的Spark官方文档。所有这些类型都很有用,但用户几乎不会用到纯静态的DataFrame对象,而是会一直操作和转换它们。接下来将要介绍结构化API中的执行过程。

Overview of Structured API Execution

  本节将演示用户代码是如何在集群上执行的,这对理解编写代码过程和在集群上执行代码的过程都很有帮助,也有助于后期的调试。接下来我们将针对一个结构化API查询任务,逐步分析从用户代码到执行代码的过程。步骤如下:

  1. 编写DataFrame / Dataset / SQL代码。
  2. 如果是有效代码, Spark会将其转换为一个逻辑执行计划。
  3. Spark将此逻辑执行计划转化为一个物理执行计划,并在此过程中检查优化。
  4. Spark通过RDD操作,在集群上执行该物理执行计划。

  我们编写的代码通过控制台提交给Spark,或以一个Spark作业的形式提交。然后代码将交由Catalyst优化器决定如何执行,并指定一个执行计划。最后代码被运行,并将结果返回给用户。下图展示了整个过程。

Logical Planning

  执行的第一阶段旨在获取用户代码并将其转换为逻辑计划。下图展示了该过程。

  逻辑计划仅代表一组抽象转换,并不涉及executors或drivers,它只是将用户的表达式集合转换为最优化的版本。它通过将用户代码转换为未解析的逻辑计划来实现这一点。该计划暂时未解析,因为尽管代码可能有效,但它引用的表或列有可能不存在。Spark使用catalog(所有表和DataFrame信息的存储库)在分析器中解析列和表。如果目录中不存在所需的表或列,分析器可能会拒绝未解析的逻辑计划。如果分析器可以解析它,结果将通过Catalyst优化器传递, Catalyst优化器是一组规则的集合,其试图通过谓词下推或选择操作来优化逻辑计划。用户也可以扩展Catalyst优化器来支持自己的特定领域优化策略。
Physical Planning

  在成功创建优化的逻辑计划后, Spark开始执行物理计划流程。物理计划(通常称为Spark计划)通过生成不同的物理执行策略,并通过代价模型进行比较分析,从而指定如何在集群上执行逻辑计划,具体流程如下图所示。例如执行一个连接操作就会涉及代价比较,它通过分析数据表的物理属性(表的大小或分区的大小),对不同的物理执行策略进行代价比较,选择合适的物理执行计划。

  物理计划会产生一系列的RDD和transformations操作。这就是Spark被称为编译器的原因,因为它将把DataFrame、 Dataset和SQL中的查询,编译为一系列RDD转换操作。
Execution

  在选择一个物理计划时, Spark将所有代码运行在底层编程接口RDD上。 Spark在运行时执行进一步优化,生成可以在执行期间优化task或stage的本地Java字节码,最终将结果返回给用户。

Conclusion

  在本章中,我们介绍了Spark结构化API,以及Spark如何将你的代码转换为在集群上实际执行的代码。接下来的分享中,将介绍一些核心概念以及如何使用结构化API的关键功能。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Welcome to this first edition of Spark: The Definitive Guide! We are excited to bring you the most complete resource on Apache Spark today, focusing especially on the new generation of Spark APIs introduced in Spark 2.0. Apache Spark is currently one of the most popular systems for large-scale data processing, with APIs in multiple programming languages and a wealth of built-in and third-party libraries. Although the project has existed for multiple years—first as a research project started at UC Berkeley in 2009, then at the Apache Software Foundation since 2013—the open source community is continuing to build more powerful APIs and high-level libraries over Spark, so there is still a lot to write about the project. We decided to write this book for two reasons. First, we wanted to present the most comprehensive book on Apache Spark, covering all of the fundamental use cases with easy-to-run examples. Second, we especially wanted to explore the higher-level “structured” APIs that were finalized in Apache Spark 2.0—namely DataFrames, Datasets, Spark SQL, and Structured Streaming—which older books on Spark don’t always include. We hope this book gives you a solid foundation to write modern Apache Spark applications using all the available tools in the project. In this preface, we’ll tell you a little bit about our background, and explain who this book is for and how we have organized the material. We also want to thank the numerous people who helped edit and review this book, without whom it would not have been possible.

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值