hive 修改cluster by算法_Spark SQL连接 Hive源码深度剖析

val spark= SparkSession.builder().master (”local").enableHiveSupport().getOrCreate() 
spark.sq!(”CREATE TABLE IF NOT EXISTS src (key INT, value STRING )”) 
spark. sql( "LOAD DATA LOCAL INPATH ’ kvl. txt' INTO TABLE src”) 
spark. sql( ''SELECT * FROM src”) . show() 

上面这串代码是2.0的spark版本之后预处理环境部分,enableHiveSupport则是配置信息 conf 中会将 Catalog 信息( spark.sql. cataloglmplementation )设置为“hive ”,这样在 SparkSession 根据配置信息反射获取SessionState 对象时就会得到与 Hive 相关的对象 。

c20db01ede237e4f65c25be42ffc4bd5.png

6932b37ba4ab2cf72643c9dd54f6520b.png

再看另外一个重要概念,HiveSessionState,其实通过HiveSessionStateBuilder创建的。

生成Hive感知的`SessionState`的构建器在HiveSessionStateBuilder.scala中。

3f810425534cfde5915bfab6fb098fe6.png

HiveSessionState会创建三个重要成员

HiveSessionCatalog;Analyzer;SparkPlanner

ac4a5a5d0ce6aa8fd141a8cc6eb66506.png

a110ee37503a16199004373a0f352269.png

7160a497e9131677c8548b1d9626ab2c.png

HiveSessionCatalog

HiveSessionCatalog继承SessionCatalog

bce06dda67e564be93b1666d18b67b38.png

SessionCatalog

8d99ae5a6ad44211df7259989e5a5c07.png

而实际操作存储数据的是ExternalCatalog

Spark在Hive场景下,HiveSessionCatalog继承了SessionCatalog, HiveExternalCatalog则继承了ExternalCatalog。在HiveExternalCatalog中,对数据库、数据表、数据分区和注册函数等信息的读取与操作都通过HiveClient完成 。 顾名思义,Hive Client是用来与Hive进行交互的客户端,在Spark SQL中是定义了各种基本操作的接口,具体实现为HiveClientimpl 对象 。

bd7d2d829d1f36c5a6ba72e35070c0a2.png

ExternalCatalog分别从,通用层面;数据库层面;数据表层面;分区层面;方法层面。对数据存储操作

0798d4f363a5de3e8ade720ae8213515.png

10656d1b61535b470f914dcce9cd391f.png

3a99b7d384d76df6a702792fa0b4e5db.png

f082d19e22df16b9e84cd71f2ba3464f.png

df455696d6b62faa256efcdbb4d37389.png

在 Spark SQL 中是定义了各种基本操作的接口,具体实现为 HiveClientimpl 对象 。 然而在实际场景中 ,因为历史遗留的原因,往往会涉及多种 Hive 版本,为了有效地支持不同版本, Spark SQL 对 HiveClient的实现由 HiveShim 通过适配 Hive 版本号( HiveVersion )来完成。Hive 版本与对应的 Shim 实现关系如下

83a13b8d1fec92f02229bc2ead492c24.png

真正创建 HiveClient 的操作位于 IsolatedClientLoader 类中 。一般情况下, Spark SQL 只会通过 HiveClient 访问 Hive 中的类,为了更好地隔离, IsolatedClientLoader 将不同的类分成 3 种,不同种类的加载和访问规则各不相同 。

  • 共享类( Shared classes ):包括基本的Java、 Scala 、 Logging 和 Spark 中的类,这些类通过当前上下文的 ClassLoader 加载,调用 HiveClient 返回的结果对于外部来说是可见的 。
  • Hive 类( Hive classes) : 通过加载 Hive 的相关 Jar 包得到的类。 默认情况下,加载这些类的 ClassLoader 和加载共享类的 ClassLoader 并不相同,因此,无法在外部访问这些类。
  • 桥梁类( Barrier classes ): 一般包括 HiveClientlmpl 与 Shim 类,在共享类与 Hive 类之间起到了桥梁的作用, Spark SQL 能够通过这个类访问 Hive 中的类 。 每个新的 HiveClientlmpl实例都对应一个特定的 Hive 版本

ccf42105948dffb38b37fa2a03862a4a.png

创建 HiveClient 的具体实现逻辑(删除了异常处理的代码)如以下代码所示。当isolationOn 为false时,直接创建一个HiveClientimpl对象并返回。代码中的classLoader为 MutableURLClassLoader 类型,可以直接通过 add URL 方法加载所需要的类 。

HiveSessionCatalog 中一个重要的方法是查找数据表( lookupRelation ) ,由于HiveSessionCatalog是继承SessionCatalog,自然继承了其对应的方法。

03f7c7e4954e7ce1e47f0e77d055288a.png

2cec74ae49ced3b5ae6fda6978a1898e.png

Analyzer 之 Hive-Specific 分析规则

在逻辑计划阶段,HiveSessionState中仍然会生成新的Analyzer可以看到,不同之处在于 extendedCheckRules中少了HiveOnlyCheck规则,且extendedResolutionRules中多了 ParquetConversions和OrcConversions两条规则 。在默认的Analyzer中,HiveOnlyCheck 规则会遍历逻辑算子树,如果发现 CreateTable 类型的节点且对应的 CatalogTable 是 Hive 才能够提供的,则会抛出 AnalysisException 异常,因此在Hive场景下,这条规则不再需要。

顾名思义, ParquetConversions 与 OrcConversions 用来处理 Parquet 数据表文件与 ORCFile数据表文件。在 Hive 模块中,数据表统一 用 MetastoreRelation 表示,而MetastoreRelation 包含了复杂的 partition 信息 。 当 一个查询涉及的数据表不涉及分区情况时-,为了得到更优的性能,可以将 MetastoreRelation 直接转换为数据源表 ( Data source table ) 。 具体来讲,包含两种情况。

  • 读数据表,将 LogicalPlan 中所有满足条件的 MetastoreRelation 转换为 Parquet ( ORCFile) 文件格式所对应的 LogicalRelation 节点 。
  • ·写数据表,即 InsertlntoTable 逻辑算子节点,同样的逻辑替换目标数据表 MetastoreRel ation为对应的 LogicalRelation 节点 。 具体的实现可以参见 convertToLogicalRelation 方法。

e71cb2700ecf5e741e34f271e30d1688.png

SparkPlanner 之 Hive-Specific 转换策略

29d9fd10945423184b761dfed73c9f33.png

HiveTableScans 策略与前面章节中介绍过的 FileSourceStrategy 类似,同样是匹配 Physical Operation 模式,区别在于 FileSourceStrategy 生成的物理执行计划的节点为 File­SourceScanExec ,而 Hive 中则对应 HiveTableScanExec 节点 。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值