首先说一下,这里解决的问题应用场景:

sparksql处理Hive表数据时,判断加载的是否是分区表,以及分区表的字段有哪些?再进一步限制查询分区表必须指定分区?

这里涉及到两种情况:select SQL查询和加载Hive表路径的方式。这里仅就"加载Hive表路径的方式"解析分区表字段,在处理时出现的一些问题及解决作出详细说明。

如果大家有类似的需求,笔者建议通过解析Spark SQL logical plan和下面说的这种方式解决方案结合,封装成一个通用的工具。

问题现象

sparksql加载指定Hive分区表路径,生成的DataSet没有分区字段。

如,

sparkSession.read.format("parquet").load(s"${hive_path}"),hive_path为Hive分区表在HDFS上的存储路径。

hive_path的几种指定方式会导致这种情况的发生(test_partition是一个Hive外部分区表,dt是它的分区字段,分区数据有dt为20200101和20200102):

1. hive_path为"/spark/dw/test.db/test_partition/dt=20200101"

2. hive_path为"/spark/dw/test.db/test_partition/*"

因为牵涉到的源码比较多,这里仅以示例的程序中涉及到的源码中的class、object和方法,绘制成xmind图如下,想细心研究的可以参考该图到spark源码中进行分析。

问题分析

我这里主要给出几个源码段,结合上述xmind图理解:

在没有指定参数basePath的情况下:

1. hive_path为/spark/dw/test.db/test_partition/dt=20200101

sparksql底层处理后得到的basePaths: Set(new Path(“/spark/dw/test.db/test_partition/dt=20200101”))【伪代码】

leafDirs: Seq(new Path(“/spark/dw/test.db/test_partition/dt=20200101”))【伪代码】

2. hive_path为/spark/dw/test.db/test_partition/*

sparksql底层处理后得到的basePaths: Set(new Path(“/spark/dw/test.db/test_partition/dt=20200101”),new Path(“/spark/dw/test.db/test_partition/dt=20200102”))【伪代码】

leafDirs: Seq(new Path(“/spark/dw/test.db/test_partition/dt=20200101”),new Path(“/spark/dw/test.db/test_partition/dt=20200102”))【伪代码】

这两种情况导致源码if(basePaths.contains(currentPath))为true,还没有解析分区就重置变量finished为true跳出循环,因此最终生成的结果也就没有分区字段:

解决方案(亲测有效)

1. 在Spark SQL加载Hive表数据路径时,指定参数basePath,如

sparkSession.read.option("basePath","/spark/dw/test.db/test_partition")

2. 主要重写basePaths方法和parsePartition方法中的处理逻辑,同时需要修改其他涉及的代码。由于涉及需要改写的代码比较多,可以封装成工具

关联文章:

Spark SQL

Apache Hive

必须掌握的分布式文件存储系统—HDFS

最新文章

  1. 在Win7 64位操作系统下安装Oracle 10g
  2. 直接拿来用!最火的Android开源项目(完结篇)
  3. pydev导入eclipse
  4. TF255466: Team Foundation Server 的配置过程无法继续。以前的更新或安装需要重
  5. BOM组件物料重复检查
  6. working copy locked 问题
  7. Viz World and Viz Curious Maps 教程 -- 基础篇
  8. P2286 [HNOI2004]宠物收养场
  9. open-falcon(v0.2)安装grafana部署
  10. LabView ModBus安装
  11. centos环境下使用CPAN安装perl模块
  12. [转帖]Docker的数据管理(volume/bind mount/tmpfs)
  13. C# Note32: 查漏补缺
  14. docker安装和使用
  15. spingMVC+mybatis+spring-session共享内存配置
  16. java 数组(二)
  17. 【usaco 2006 feb gold】 牛棚安排
  18. 在SpringTest中将Mockito的mock对象通过spring注入使用
  19. zeromq 笔记
  20. 简述对Vuex的理解

热门文章

  1. [Luogu P3203] [HNOI2010]弹飞绵羊 (LCT维护链的长度)
  2. NOIP 2018 D1 解题报告(Day_1)
  3. 知识全聚集 .Net Core 技术突破 | 我用C#手把手教你玩微信自动化一
  4. Mybatis的二级缓存、使用Redis做二级缓存
  5. reids 入门
  6. Docker - 解决创建 tomcat 容器镜像却无法访问页面的问题
  7. 僵尸进程与SIGCHLD信号
  8. centos7 安装telnet
  9. history命令的优化
  10. Nacos 多环境配置