原理
大概有6步:
- sql 语句经过 SqlParser 解析成 Unresolved Logical Plan;
- analyzer 结合 catalog 进行绑定,生成 Logical Plan;
- optimizer 对 Logical Plan 优化,生成 Optimized LogicalPlan;
- SparkPlan 将 Optimized LogicalPlan 转换成 Physical Plan;
- prepareForExecution()将 Physical Plan 转换成 executed Physical Plan;
- execute()执行可执行物理计划,得到RDD;
样例
我们以spark源代码的例子来说。
SparkSession 实例化
在使用hive的场景下,会使用spark.sql.catalogImplementation=hive. 后续会初始化HiveExternalCatalog, HiveSessionStateBuilder
HiveSessionStateBuilder
看一下这个类的结构。
- 初始化HiveExternalCatalog, 所有与hive相关的CRUD都是通过这个类来完成的。
- resourceLoader 资源加载器,主要初始化加载HiveClient -HiveSessionResourceLoader 主要和架子啊jar包有关系。包括一些第三方jar。
- HiveSessionCatalog 主要和UDF有关。加载UDF就需要这个类
- HiveMetastoreCatalog 主要和hive-metastore的元数据信息有关。
- analyzer 解释器 的一些规则初始化,里面包含了一些比较重要的规则,DataSourceAnalysis, HiveAnalysis,这些会在后面讲。
- optimizer 优化器, 包含了一个PruneHiveTablePartitions。主要是下推到hive执行的优化器。
- planner 物理执行计划,包含了一个HiveTableScans。
SessionState
SessionState是sparkSession中一个重要的类。
如果使用hive 就会实例化HiveSessionStateBuilder。
在这个地方对SessionState进行了实例化,说一下里面几个比较重要的参数
SharedState
包含一些在session之间共享的状态。
- warehousePath 默认是加载hive-site.xml /app/hive/wareshouse
- cacheManager 缓存,主要存储一些查询的结果已被后续使用。
- externalCatalog 默认实例化HiveExternalCatalog,增加了ExternalCatalogEventListener事件的监听器,所有CRUD操作均可以获取到。这个可以作为扩展程序使用。
- globalTempViewManager 临时view的管理器。
ExperimentalMethods
如果有其他的优化器,解析策略,可以使用这个来替换掉spark自带的。
FunctionRegistry
函数注册器包括自带的函数和自定义的函数。在Analyzer中使用。
UDFRegistration
自定义UDF注册器
ParserInterface
sqlParser = SparkSqlParser 外层的包装器,包装了继承自AstBuilder的类。
QueryExecution
执行器的对象。这个类包含了Catalyst的核心代码。后续再讲。