Spark-源码学习-SparkSQL-架构设计-SQL 引擎-数据结构-InternalRow
一、概述
数据处理首先需要考虑如何表示数据。对于关系表来讲,通常操作的数据都是以 “行” 为单位的。在 SparkSQL 内部实现中, InternalRow 就是用来表示一行行数据的类。此外,InternalRow 中的每一列都 是 Catalyst 内部定义的数据类型。
二、结构
从类的定义来看,InternalRow 作为一个抽象类,包含 $numFields()$ 和 $update$ 方法,以及各列数据对应的 $get$ 与 $set$ 方法,但具体的实现逻辑体现在不同的子类中。
需要注意的是, InternalRow 中都是根据下标来访问和操作列元素的。
三、InternalRow 继承体系
3.1. BaseGenericInternalRow
同样是一个抽象类,实现了 InternalRow 中定义的所有 get 类型方法,这些方法的实现都通过调用类中定义的 genericGet 虚函数进行
3.1.1. GenericInternalRow
使用数组作为底层存储的 InternalRow 实现。
1 | def this(size: Int) = this(new Array[Any](size)) |
3.1.2. SpecificInternalRow
SpecificInternalRow 和 GernericInternalRow 的区别在于构造参数的类型,GernericInternalRow 的构造参数类型是 Array[Any], 一旦创建就不允许通过 $set$ 操作修改;而SpecificInternalRow 的构造参数类型是 Array[MutableValue],允许通过 $set$ 操作修改。
3.1.3. PartitionInternalRow
3.1.4. LongArrayInternalRow
3.1.5. MutableUnsafeRow
UnsafeRow 的辅助类,用于更新 UnsafeRow中 的字段值,主要使用地方在 ColumnAccessor
3.2. UnsafeRow
不采用 Java 对象存储的方式,避免了 JVM 中垃圾回收的代价。 此外, UnsafeRow 对行数据进行了特定的编码,使得存储更加高效。
3.3. Columnar 相关
3.3.1. ColumnarRow
主要用于 ColumnVector 中 getStruct 时返回列原始信息
3.3.2. MutableColumnarRow
是 ColumnarRow 的可变版本,主要是用于 hash map 的聚合计算
3.3.3. ColumnarBatchRow
3.4. JoinedRow
该类主要用于 Join 操作,将两个 InternalRow 放在一起形成新的 InternalRow。 使用时需要注意构造参数的顺序 。