SparSQL——基本类和常见概念

Plan分类

在这里插入图片描述

  1. 未解析的逻辑算子树(Unresolved LogicalPlan,仅仅是数据结构,不包含任何数据信息等)
  2. 解析后的逻辑算子树(Analyzed LogicalPlan,节点中绑定各种信息)
  3. 优化后的逻辑算子树( optimized LogicalPlan ,应用各种优化规则对 些低效的逻辑计划进行转换)
  4. 物理算子树的列表(Iterator [PhysicalPlan] ,同样的逻辑算子树可能对应多个物理算子树)
  5. 从列表中按照一定的策略选取最优的物理算子树(SparkPlan)
  6. "准备后"的物理算子树(Prepared SparkPlan,对选取的物理算子树进行提交前的准备工作,例如,确保分区操作正确、物理算子树节点 重用、执行代码生成等)

InternalRow

SparkSQL 内部实现中,InternalRow 就是用来表示一行行数据的类,物理算子树节点产生和转换的 RDD 类型即为 RDD [InternalRow]
在这里插入图片描述

  • BaseGenericlnternalRow:抽象类,实现了 InternalRow 中定义的所有 get 类型方法,这些方法的实现都通过调用类中定义的genericGet虚函数进行,该函数的实现在下级子类中
    • GenericlnternalRow的构造参数是 Array[Any]类型,采用对象数组进行底层存储, genericGet 也是直接根据下标访问的。数组是非拷贝的,一旦创建,就不允许通过 set 操作进行改变
    • SpecificInternalRow则是以Array[MutableValue]为构造参数的,允许通过 set 操作进行修改
    • MutableUnsafeRow用来支持对特定的列数据进行修改
  • JoinedRow:顾名思义,该类主要用于 Join 操作,将两个 InternalRow 放在 起形成新的 InternalRow 使用时需要注意构造参数的顺序
  • UnsafeRow:不采用 Java 对象存储的方式,避免了 JVM 中垃圾回收(GC)的代价,此外, UnsafeRow 对行数据进行了特定的编码,使得存储更加高效,是Tungsten计划的重要内容

TreeNode

在Catalyst中,TreeNode 类是 SparkSQL 中所有树结构的基类,定义了 系列通用的集合操作和树遍历操作接口。
TreeNode一直在内存里维护,不会dump到磁盘以文件形式存储,且无论在映射逻辑执行计划阶段,还是优化逻辑执行计划阶段,树的修改都是以替换已有节点的方式进行的。
在这里插入图片描述

Expression

表达式Expression一般指的是不需要触发执行引擎而能够直接进行计算的单元。

  • eval:实现了表达式对应的处理逻辑,也是其他模块调用该表达式的主要接口
  • genCode和doGenCode:用于生成表达式对应的java代码
  • foldable:该属性用来标记表达式能否在查询执行之前直接静态计算。如果一个表达式是可折叠的,意味着Spark可以在执行计划生成阶段就对该表达式进行优化或简化。这种优化可以减少运行时的计算量,从而提高性能。例如3+2可以直接优化成5,如果表达式包含变量或者动态输入,则通常不会被视为可折叠的。
  • deterministic:该属性用来标记表达式是否为确定性的,即每次执行eval函数的输出是否都相同。考虑到 Spark 分布式执行环境中数据的 Shuffle 操作带来的不确定性,以及某些表达式(如 Rand 等)本身具有不确定性,该属性对于算子树优化中判断谓词能否下推等很有必要
  • nullable:该属性用来标记表达式是否可能输出Null值,一般在生成的java代码中对相关条件进行判断
  • references:返回值为 AttributeSet 类型,表示该 Expression 中会涉及的属性值,默认情况为所有子节点中属性值的集合
  • canonicalized:返回经过规范化(Canonicalize)处理后的表达式。规范化处理会在确保输出结果相同的前提下通过一些规则对表达式进行重写。为了简化表达式的比较,并使得优化器能够更好地识别和利用等价变换。例如表达式 a > bb < a 都优化成标准的a > b
  • semanticEquals:判断两个表达式在语义上是否等价。基本的判断条件是两个表达式都是确定性的( deterministic true )且两个表达式经过规范化处理后(Canonicalized)仍然相同.

在这里插入图片描述

常用expression

  • Nondeterministic接口:具有不确定性的Expression,其中deterministic和foldable属性都默认返回false,典型的实现包括MonotonicallyIncreasingID表达式、Rand和Randn表达式等。
  • Unevaluable接口:非可执行的表达式,即调用其eval函数会抛出异常。该接口主要用于生命周期不超过逻辑计划解析和优化阶段的表达式,例如Star(*)表达式在解析阶段就会被展开成具体的列集合。
  • CodegenFallback接口:不支持代码生成的表达式。某些表达式涉及第三方实现(例如Hive的UDF)等情况,无法生成Java代码,此时通过CodegenFallback直接调用,该接口中实现了具体的调用方法。
  • LeafExpression:叶子节点类型的表达式,即不包含任何子节点,因此其children方法通常默认返回Nil值。该类型的Expression目前大约有30个,包括Star、CurrentDate、Pi表达式等。
  • UnaryExpression:一元类型表达式,只含有一个子节点。这种类型的表达式总量110多种,较为庞大。其输入涉及一个子节点,例如Abs操作、UpCast表达式等。
  • BinaryExpression:二元类型表达式,包含两个子节点。这种类型的的表达式数目也比较庞大,大约有80种。比较常用的是一些二元的算数表达式,例如加减乘除操作、RLike函数等。
  • TernaryExpression:三元类型表达式,包含3个子节点。这种类型白的表达式数目不多,大约有10种,大部分都是一些字符串操作的函数,非常典型的例子可以参考Substring函数,其子节点分别是字符串、下标和长度的表达式。

在这里插入图片描述

LeafExpression

叶子节点,没有子节点。children是Nil
在这里插入图片描述

Literal是LeafExpression的一个实现类,是用来包装常量的。
可以看到核心方法eval就是直接返回value

UnaryExpression

一元类型表达式,一个输入一个输出。children是child::Nil,只有一个child。
eval方法是调用child的eval方法(形成循环调用,直到叶子节点),根据返回值调用nullSafeEval方法。
nullSafeEval是一个抽象方法,需要具体的实现类来实现。
在这里插入图片描述

Base64是一个UnaryExpression的实现类。可以看到nullSafeEval方法是具体的Base64加密的逻辑。
在这里插入图片描述

别的Expression类和上面两个类似。

数据类型

比较简单,可以对照一下常用的数据类型。
在这里插入图片描述

  • 9
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值