项目介绍

github: https://github.com/oap-project/gluten
官网: https://oap-project.github.io/gluten

源码结构

目录包结构,有 java 的和 C++ 的
c++ 的

  • backends-clickhouse
  • backends-velox
  • cpp
  • cpp-ch
  • dev

java 的

  • gluten-core
  • gluten-ui

管理,打包,控制spark 多版本的

  • ep
  • gluten-ut
  • package
  • shims
  • tools

其他

  • gluten-celeborn
  • gluten-data
  • substrait

Java 部分

core 模块

核心入口点是 GlutenPlugin,这个类继承了 SparkPlugin
GlutenPlugin 又分别创建了两个类

  • GlutenDriverPlugin
  • GlutenExecutorPlugin

GlutenDriverPlugin 的主要逻辑

  • 将各种 metrics 注册到 SparkUI 中,这里调用了 GlutenEventUitls
  • 监听各种 SparkListener 事件,创建了 GlutenSQLAppStatusListener
  • 调用 ExpressionUtil,创建各种 表达式转换
  • 对 RPC 通讯做了一些扩展 GlutenDriverEndpoint
  • 调用 BackendsApiManager,这里内部会做各种初始化,包含各种接口
  • GlutenSessionExtensions,注入各种规则

BackendsApiManager 内部会做初始化,然后返回一个 Wrapper
Wrapper 的结构如下,里面包含了各种接口

1
2
3
4
5
6
7
8
9
  private case class Wrapper(
      glutenBackendName: String,
      contextApi: ContextApi,
      iteratorApiInstance: IteratorApi,
      sparkPlanExecApiInstance: SparkPlanExecApi,
      transformerApiInstance: TransformerApi,
      validatorApiInstance: ValidatorApi,
      metricsApiInstance: MetricsApi,
      settings: BackendSettingsApi)

Backend 这个 trait 相关接口如下:

  • IteratorApi
  • SparkPlanExecApi
  • TransformerApi
  • ValidatorApi
  • MetricsApi
  • BackendSettingsApi
  • ContextApi

各种继承关系如下,细箭头是调用,粗箭头是继承,绿色是 Spark 类,黄色是 Gluten 类:

Gluten 注入很多规则,使用的是 SparkSessionExtensions 作为入口点注入的 GlutenDriverPlugin 会调用到 GlutenSparkExtensionsInjector
这个类有 四个实现类

  • ColumnarQueryStagePrepOverrides
  • ColumnarOverrides
  • StrategyOverrides
  • OthersExtensionOverrides

在这 四个类中,又分别注入了一些规则,比如

  • injectColumnar
  • injectQueryStagePrepRule
  • injectResolutionRule
  • injectOptimizerRule
  • injectPlannerStrategy
  • injectFunction

各种继承关系如下:

ui 模块

这块部分基本是对 spark-ui 的一个扩展,将一些自定义的 metrics 注册到 spark-ui 上
依赖用了细箭头、继承用了粗箭头,整体关系如下:

核心的入口点是:GlutenEventUtils,由这个类来创建 listener、ui-page
还有一个 history,这个是通过 META_INFO 目录下的 services 来注册的

UI 部分

  • 这里的核心类是 SparkUI,是对 jetty 的封装
  • 通过 SparkContext,获取到 SparkUI,将 GlutenSQLTab 加入到 SparkUI 中
  • GlutenSQLTab 中,又将 GlutenAllExecutionsPage 加入到 page 中
  • GlutenAllExecutionsPage 内创建了 GlutenExecutionPagedTable,表示一个 HTML 的 table
  • 再往下创建 GlutenExecutionDataSource,用来设置分页的,避免单个页面过大
  • GlutenSQLTab 还关联了 GlutenSQLAppStatusStore
  • GlutenSQLAppStatusStore 则将具体存储实现委托给了 KVStore 接口
  • KVStore 包含了多个实现类,如InMemoryStore、LevelDB、HybridStore、ElementTrackingStore

将 GlutenSQLTable 加入到 UI 中

1
2
3
4
5
  def attachUI(sc: SparkContext): Unit = {
    val kvStore = sc.statusStore.store.asInstanceOf[ElementTrackingStore]
    val statusStore = new GlutenSQLAppStatusStore(kvStore)
    sc.ui.foreach(new GlutenSQLTab(statusStore, _))
  }

listener 继承了 SparkListener,这里只实现了 onOtherEvent 函数

1
2
3
4
5
6
7
  override def onOtherEvent(event: SparkListenerEvent): Unit = event match {
    case e: SparkListenerSQLExecutionStart => onSQLExecutionStart(e)
    case e: SparkListenerSQLExecutionEnd => onSQLExtensionEnd(e)
    case e: GlutenBuildInfoEvent => onGlutenBuildInfo(e)
    case e: GlutenPlanFallbackEvent => onGlutenPlanFallback(e)
    case _ => // Ignore
  }

参考