Spark SQL解析查询parquet格式Hive表获取分区字段和查询条件
首先说一下,这里解决的问题应用场景:
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方法中的处理逻辑,同时需要修改其他涉及的代码。由于涉及需要改写的代码比较多,可以封装成工具
关联文章:
最新文章
- 在Win7 64位操作系统下安装Oracle 10g
- 直接拿来用!最火的Android开源项目(完结篇)
- pydev导入eclipse
- TF255466: Team Foundation Server 的配置过程无法继续。以前的更新或安装需要重
- BOM组件物料重复检查
- working copy locked 问题
- Viz World and Viz Curious Maps 教程 -- 基础篇
- P2286 [HNOI2004]宠物收养场
- open-falcon(v0.2)安装grafana部署
- LabView ModBus安装
- centos环境下使用CPAN安装perl模块
- [转帖]Docker的数据管理(volume/bind mount/tmpfs)
- C# Note32: 查漏补缺
- docker安装和使用
- spingMVC+mybatis+spring-session共享内存配置
- java 数组(二)
- 【usaco 2006 feb gold】 牛棚安排
- 在SpringTest中将Mockito的mock对象通过spring注入使用
- zeromq 笔记
- 简述对Vuex的理解
热门文章
- [Luogu P3203] [HNOI2010]弹飞绵羊 (LCT维护链的长度)
- NOIP 2018 D1 解题报告(Day_1)
- 知识全聚集 .Net Core 技术突破 | 我用C#手把手教你玩微信自动化一
- Mybatis的二级缓存、使用Redis做二级缓存
- reids 入门
- Docker - 解决创建 tomcat 容器镜像却无法访问页面的问题
- 僵尸进程与SIGCHLD信号
- centos7 安装telnet
- history命令的优化
- Nacos 多环境配置