Spark SQL 基础框架和核心组件

Spark SQL 基础框架和核心组件

今天被问到Spark SqlDataframe的关系,当时没有描述好。事后脑海中关于它们的一些细节才一一涌现出来。还是理解的不够深刻,所以这里重新做下相关概念知识的整理也算是一种复习。

1. Spark SQL发展史

Spark的早期版本,为什么解决Hive查询在性能上的问题,在Spark生态圈引入了一个名为Shark的项目。(使用Spark的计算引擎而不是MapReduce来执行Hive查询)。Shark是在Hive代码库上构建的,使用Hive查询编译器来解析Hive查询并生成一个抽象语法树,它会转化为一个具有某些基本优化的逻辑计划。Shark应用了额外的优化手段并创建了一个RDD操作额度物理计划,然后在Spark上执行。基于这种对Hive的过分依赖,也让Shark本身具有一些问题:

  1. 只适用于查询Hive表。无法在RDD上进行关系查询。
  2. Spark程序中将Hive-QL作为字符串运行容易出错。
  3. 它的Hive优化器是为MapReduce附案例创建的,很难讲Spark扩展到新的数据源和新的处理模型。
    基于以上原因,Spark团队终止了Shark,原班人马合并全力开发Spark SQL。下面是Spark SQL的发展史。

    2. Spark SQL的构架

    Spark SQL是在Spark核心执行引擎上的一个库,它借助JDBC/ODBC公开了SQL接口,用于数据仓库应用程序,或通过命令行进行交互式查询。因此任何商务智能(BI)工具都可以连接到Spark SQL以内存速度执行分析
    它还提供了Java、Scala、Python、R支持的Dataset APIDataframe API。(注意:Python和R不支持Dataset)
    Spark SQL用户可以使用Data Sourse API从各种数据源读取和写入数据,从而创建Dataframe 或者 Dataset

    Spark SQL还扩展了用于所有其他Spark库(如 SparkR、SparkStreaming、Structred Streaming、ML、MLlib、GraphX)的DataSet API、Dataframe API和Data Sources API。如下图所示:

Spark SQL引入了Catalyst的可扩展优化器,一直吃大多数常见的数据源和算法。Catalyst支持添加新的数据源、优化规则和某些领域(如机器学习)使用的数据类型。

3. Spark SQL的四个组件

Spark SQL 中的四个组件分别是:SQL、 Data Sources API、 DataFrame API、 DataSet API
下面一一展开:

  • Spark SQL可以使用SQL语言向Hive表写入读取数据。

    SQL通过ODBC/JDBC或命令行选项在Java、Scala、Python、R语言中使用。在编程语言中使用SQL时,结果会转换成DataFrame。SQL的优点是可以轻松的处理Hive表,并且可以利用Thrift服务器将BI工具连接到分布式SQL引擎,并利用JDBC/ODBC接口提交SQL或HQL查询。

  • Data Sources API为使用Spark SQL 读取和写入数据提供了统一的接口。

    Data Sources API的优点有:

    1. 容易加载/保存Dataframe
    2. 通过到数据源的*谓词下推*方式进行高效的数据访问,采用这种方式能从数据源读取更少的数据。
    3. 为任何新的数据源构建库
    4. 无需包含在Spark代码中
    5. 很容易与Spark组件包共享新的数据源。
    
    --谓词下推的思路是让筛选数据的条件表达式尽可能靠近数据源执行,从而减少数据额移动和传输。谓词就是筛选数据的条件,下推就是让这些筛选动作尽量在靠近数据源的位置执行。
    
  • DataFrame API旨在让大数据分析工作更为简单易行。

    这个API收到了R和Python(Pandas库)中的DataFrame的启发,但他被实际用于大规模数据集的分布式处理一支持大数据分析。DataFrame可以看作是对现有RDD API的扩展,也是RDD纸上的一个抽象
    DataFrame的优点有:

    1. 易于使用域特定语言开发应用程序
    2. 在传统RDD基础上的高性能,并且在Scala、Java、Python、R中都具备近似性能
    3. 在数据源中自动发现模式类型(Schema)和分区
    4. 支持多种数据源
    5. 通过Catalyst优化器进行优化和代码生成
    6. 可以与RDD、DatSet、Pandas和外部数据源(RDBMS关系型数据库、HBase、Cassandra等)互操作
    
  • DataSet API

    Spark1.6 版本引入的 DataSet API 结合了 RDD 和 DataFrame的最大优点。 DatSet 会使用编码器将JVM对象转换为用 Spark 的 Tungsten 二进制格式存储的 DatSet 表形式。
    它的优点有:

    1. 和 RDD 一样,类型安全性
    2. 和 DataFrame 一样, 比 RDD 更快
    3. 与 DataFrame 和 RDD 之间具有互操性
    4. 缓存的 DatSet 专用的空间比 RDD 更少
    5. 使用编码器进行序列话比 Java 或 Kyro 序列化更快 
    

4. Dataframe 和 DataSet 的演变与优势

Spark SQL 的 DataFrame 相比 R 语言或 Python 的 DataFrame,有更丰富的隐藏后台优化。 条吗可以从文件、Pandas DataFrame、 Hive 中的表、像 MySQL 这样的外部数据库或者 RDD 中创建。 Scala、Java、Python、R 都支持 DataFrame API。 虽然 DataFrame 提供了关系操作和更高的性能,但缺乏类型安全性,这会导致运行时错误。

在 1.6 版本, DataSet 和 DataFrame 还是单独的类。在 2.0 版本中, DataSet 和 DataFrame API 被统一起来,为开发人员提供单一的 API。 DataFrame 时一个特定的 DataSet[T],其中 T = Row 的类型, 因此 DataFrame 和 DataSet 共享相同的方法。

DataSet API 支持 Scala 和 Java,还不支持 Python 和 R。 但是, DataSet API 的许多优点已经天然在 Python 和 R 语言中存在了。 DataFrame 则支持所有这四种语言。

4.1 为什么使用 DataFrame 和 DataSet

Spark 要对闭包进行计算、将其序列话,并将他们发送到执行进程。这意味着代码是以原始形式发送的,没有经过优化。 在 RDD 中无法表示结构化数据,对 RDD 进行查询也不可行。使用 RDD 很容易但有时候处理远足会把代码弄乱。与 Hadoop 的世界相比,纯手写的 MapReduce 作业可能比 Hive 和 Pig 作业慢,因为自爱 Hive 和 Pig 下会进行隐含的优化。 DataFrame 也可以用类似的方式看待。

因此,为什么要使用 DataFrame 和 DataSet,简单的答案是:速度和易用

DataFrame 提供了优化、速度、自动模式发现、使用多中数据源和多语言的支持。

4.2 优化

Catalyst 为 DataFrame 提供了两种优化方式:

  1. 谓词下推到数据源,只读取需要的数据
  2. 创建用于执行的物理计划,并生成比手写代码更优化的 JVM 字节码。

和 RDD 不同, DataFrame 并不定义 DAG 图。 它会创建抽象语法书, Catalyst 引擎会使用基于规则和机遇开销的优化方法对其进行解析、检查和改进。

4.3 速度


上图展示了在单个机器上对1000万个证书对的 groupby 聚合操作。 Scala 和 Python 的 DataFrame 操作具有类似的执行时间,因为条吗都被便衣为相同的 JVM 字节码用来执行。

DataSet 使用优化的编译器把对象进行序列话和反序列化,以便进行处理并通过网络传输。 这些编码器比 Java 或 Kryo 序列话具有更高的性能。

4.4 自动模式发现

要从 RDD 创建 DataFrame,必须提供一个模式。而从 JSON、Parquet 和 ORC 文件创建 DataFrame 时,会自动发现一个模式,包括分区的发现。 Data Sources API 框架让这种情况成为可能。

4.5 多数据源,多编程语言

DataFrame API 支持按照最常用的格式(JSON、Parquet、ORC 和 Hive 表)进行读写

DataFrame API 支持本地文件系统、HDFS、S3和采用 JDBC 协议的外部 RDBMS 数据库读取数据

DataFrame API 支持第三方扩展:Avro、CSV、XML、HBase、ElasticSearch、Cassandra等。(http://spark-packages.org) 提供了第三方组件包的完整列表

Spark SQL 可以在 Java、Scala、Python、R中实现。利用 Spark SQL 的分布式 SQL 引擎,我们也可以编写纯 SQL 语句。

4.6 RDD 和其他 API 的互操作性

Dataframe 可以使用 .rdd .toDF .toPandas .toDS 方法转换为 RDD 和 Pandas Dataframe。此外 DataFrame 可以与 Spark Streaming 和机器学习组件库配合使用。

4.7 仅选择和读取必要的数据

DataFrame API 、 DataSet API 和 DataSources API 的一个优点是通过将谓词下推到数据源系统,从而提供更丰富的优化手段。 列修剪、谓词下推、分区修剪会有这些框架自动完成。 这样,只有需要用到的数据才会读取和处理。