Spark SQL(2)-InternalRow和TreeNode

 

本文主要简述InternalRow、TreeNode及其子类。

一、InternalRow

在Spark SQL的内部实现中,InternalRow就是用来表示一行行数据的,也就是说在物理计划执行的阶段,Spark SQL转换和操作的都是RDD[InternalRow]。

其UML类图如下:

      其中: 

  1. UnsafeRow:不采用java对象存储的方式,避免了JVM GC的代价。
  2. JoinRow: 用于join操作,将俩个InternalRow连接形成新的InternalRow
  3. ColumnarRow: 主要用于ColumnVector中getStruct时返回列原始信息;The data for this row E.g. the value of 3rd int field is `data.getChild(3).getInt(rowId)`.
  4. MutableColumnarRow:是ColumnarRow的可变版本,主要是用于hash map的聚合计算。
  5. MutableUnsafeRow:UnsafeRow的辅助类,用于更新UnsafeRow中的字段值,主要使用地方在ColumnAccessor

二、TreeNode

      TreeNode在逻辑计划和物理计划阶段都扮演着重要的角色TreeNode是scala.Product类型,同时它一直在内存中维护,在analyzed和optimized的阶段都是以替换现有的节点的方式来实现。

      TreeNode有俩个主要的子类,一个是Expression,代表表达式,另外一个是QueryPlan代表查询计划,它有俩个主要的子类就是逻辑查询计划(LogicPlan)、物理查询计划(Spark Plan)。

      TreeNode定义的主要的基本操作有:

  1. collectLeaves 获取当前节点的所有叶子节点
  2. collectFirst 先序遍历所有节点并返回第一个满足条件的节点
  3. withNewChildren 将当前子节点替换成新的节点
  4. transformDown 先序遍历应用规则到各个节点
  5. transfUp 后序遍历应用规则到各个节点
  6. transformChildren 递归方式遍历应用规则到各个节点

      Expression简述:

  1. foldable: 标记是否可以改表达式是否可以直接计算,1、字面量2、所有的子节点改标记都为true
  2. deterministic: 该表达式是否为确定性,即每次执行eval函数输出一致
  3. eval 返回给定的输入的结果
  4. doGenCode:生成eval的java可执行的源代码
  5. genCode: 调用doGencode执行返回包装了eval java执行源代码的ExprCode

本文主要介绍了InternalRow和TreeNode大体的结构,internalRow主要用于计划执行期间的数据转换和表达,TreeNode主要是在计划执行之前对整个计划树进行操作时的中间数据。

参考:《spark sql 内存剖析》

原文地址:https://www.cnblogs.com/ldsggv/p/13379886.html