参考:《SparkSQL内核剖析》
目录
SparkSQL背景
Spark(分布式计算框架): Spark一方面提供了更加灵活丰富的数据操作方式,MR分成几轮操作 Spark一轮可以实现。另一方面,每轮的计算结果都可以分布式地存放在内存中,下一轮作业直接从内存中读取上一 轮的数据,节省了大量的磁盘 IO 开销 。
Spark SQL :是近年来 SQL-on-Hadoop (面向 Hadoop 生态系统的 SQL 查询处理技术及框架)解决方案(包括 Hive、 Presto 和 Impala等)中的佼佼者,结合了数据库 SQL处理和 Spark分布式计算模型两个方面的技术,目标是取代传统的数据仓库。
大数据特点(5V): Volume (体量大)、 Velocity (时效高)、 Variety (类型多)、 Veracity (真实性)、 Value (价值大)。
在大部分公司中,典型的场景是将 Hadoop (HDFS)作为大数据存储的标准,而将 Spark作为计算引擎的核心 。
SQL-on-Hadoop 解决方案架构:应用层、分布式执行层(SQL转成计算模型)、数据存储层。
1.Spark基础知识
RDD简介
RDD(弹性分布式数据集 Resilient Distributed Dataset):RDD 是 Spark 的核心数据结构,其本质是一种分布式的内存抽象,表示一个只读的数据分区( Partition)集合 。
RDD的优点:将数据集缓存到内存中,使得在多个操作间可以很方便地重用数据集,支持 MapReduce 应 用、关系型数据处理、流式数据处理( Stream Processing) 和迭代型应用(图计算、机器学习等)。
依赖关系
依赖关系( Dependency) :如何从其他 RDD 衍生所必需的信息。
一个 RDD通常只能通过其他的RDD转换(map、 join和 filter等)而创建。
依赖关系分为窄依赖、宽依赖。
窄依赖:RDD 之间分区是一一对 应的。
宽依赖:下游 RDD 的每个分区与上游 RDD (也称之为父 RDD)的每个分区都有关,是多对多的关系 。数据需要在不同节点之间 Shuffle传输 。
RDD操作算子
compute函数:用于得到每个分区的数据。
RDD 的操作算子:一类是 transformation,转换RDD,构建 RDD 的依赖关系;另一类称为 action, 用来触发 RDD 的计算 ,得到 RDD 的相关计算结果或将 RDD 保存到文件系统中 。
在 Spark中,只有遇到 action,才会真正地执行 RDD 的计算(注:这被称为惰性计算,英文为 Lazy Evqluation),这样在运行时可通过管道的方式传输多个转换 。
DAG:有向无环图,RDD和依赖关系,一组确定性的操作。
Lineage信息
Lineage 信息(血缘关系):RDD 通过 Lineage 信息来完成容错,即使出现数据分区丢失,也可通过 Lineage 信息重建分区 。Lineage 保存了RDD的依赖关系。
checkpoint机制
checkpoint机制:长时间迭代型应用,中间出错,通过Lineage重建RDD也需要很长时间,checkpoint机制将数据持久化,提高性能。
DataFrame和Dataset(API)
RDD不包含任何结构信息,直接使用 RDD 时需要开发人员实现特定的函数来完成数据结构的解析。
DataFrame
DataFrame:不可变分布式弹性数据集,类似表,按列名存储,具有Schema信息,可以将结构化数据集导入DataFrame。DataFrame 的数据抽象是命名元组(对应 Row 类型),比RDD多了数据特性。
Dataset
Dataset是DataFrame的扩展。
DataFrame 本质上是一种特殊的 Dataset (Dataset[Row]类型) 。
Dataset 具有两个完全不同的 API 特征 : 强类型 (Strongly-Typed) API和弱类型(Untyped) API。 强类型一般通过 Scala中定义的 CaseClass或Java中的 Class来指定。
Dataset 提供类型安全和面向对象的编程接口,并引入了编码器( Encoder),在编译阶段完成类型安全检查,还能够生成字节码与堆外数据进行交互, 提供对各个属性的按需访问,而不必对整个对象进行反序列化操作,极大地减少了网络数据传 输的代价。
2.SparkSQL 执行过程概述
SQLQuery->逻辑计划->物理计划
SQL 语句经过 SparkSqlParser 解析生成 Unresolved LogicalPlan
逻辑计划:未解析的逻辑算子树(数据结构)->解析后的逻辑算子数->优化后的逻辑算子树
Unresolved LogicalPlan->Analyzed LogicalPlan-> Optimized LogicalPlan
物理计划:生成物理算子树的列表 Iterator[PhysicalPlan] ->选取最优物理算子树(SparkPlan)->Prepared SparkPlan
Iterator[PhysicalPlan]->SparkPlan->PreparedSparkPlan
SQLQuery->逻辑算子树>物理算子树 ->生成RDD ->执行action操作
Catalyst
Spark SQL 内部实现上述流程中平台无关部分的基础框架称为 Catalyst。
InternalRow体系
在 SparkSQL 内部实现中, InternalRow就是用来表示一行行数据的类。InternalRow中的每一列都 是 Catalyst 内部定义的数据类型 。
TreeNode体系
TreeNode类是 SparkSQL 中所有树结构的基类,定义了一 系列通用的集合操作和树遍历操作接口 。
LogicalPlan 属于 TreeNode 体系,继承自 QueryPlan 父类 。
Expression体系
表达式一般指的是不需要触发执行引擎而能够直接进行计算的单元,例如加减乘除四则运算、逻辑操作、转换操作、过滤操作等。
3.SparkSQL编译器Parser
SQL 语句经过 SparkSqlParser 解析生成 Unresolved LogicalPlan。
ANTLR (Another Tool for Language Recognition)是目前非常活跃的语法生成工具,用 Java 语言编写,基于 LL (*)解析方式,使用自上而下的递归下降分析方法。 ANTLR可以用来 产生词法分析器、语法分析器和树状分析器( Tree Parser)等各个模块,其文法定义使用类似 EBNF (ExtendedBackus-NaurForm)的方式,简洁直观。
采用访问者模式(Visitor):将算法与对象结构分离的软件设计模式。
CatalystSqlParser 仅用于 Catalyst 内部,而 SparkSqlParser 用于外部调用 。 其中,比较核心的是 AstBuilder,它继承了 ANTLR4 生成的默认 SqlBaseBaseVisitor,用于生成 SQL对应的抽象语法树 AST (Unresolved LogicalPlan); SparkSqlAstBuilder 继承 AstBuilder,并在其基础上定义了 一 些 DDL 语句的访问操作,主要在 SparkSqlParser 中调用 。
主要是用AstBuilder生成抽象语法树。
4.逻辑计划(Logical Plan)
逻辑计划:SQLQuery->未解析的逻辑算子树(数据结构)->解析后的逻辑算子数->优化后的逻辑算子树
使用SparkSqlParser将SQLQuery转换成LogicalPlan节点,节点上绑定数据信息,再进行优化。
LogicalPlan的父类QueryPlan的主要操作:输入输出、基本属性、字符串、规范化、表达式操作、约束。
LogicalPlan的类型:LeafNode(叶子节点)、UnaryNode(一元节点)、BinaryNode(二元节点)。
SparkSQL是SQL-on-Hadoop的杰出代表,结合Spark的分布式计算和数据库SQL处理,目标是取代传统数据仓库。本文从Spark基础知识如RDD、依赖关系、DataFrame和Dataset介绍,深入讲解SparkSQL的执行过程,包括逻辑计划、物理计划,以及Catalyst优化器的角色。通过对SQL的解析生成逻辑计划,再到物理计划的执行,展示了SparkSQL的强大计算能力。
2133

被折叠的 条评论
为什么被折叠?



