文章目录
1. Hive版本
Hive 1.2.1000.2.6.5.0-292
2.问题背景
交付项目上基本所有的脚本任务,都是使用hive脚本的方式生成数据,但是dolphinscheduler的数据质量sql,是基于sparksql构建的
3.问题现象
在hive里执行sql
select count(*) from dw_jck_xs_xjjbsj
得到 2023003 条数据
在sparksql里执行同样的sql
得到 0 条数据
4.原因分析
1).分析原因可能是缓存
spark缓存机制: 为了提高性能会缓存Parquet的元数据信息。当通过Hive或其他方式更新了Parquet表时,缓存的元数据信息未更新,导致Spark SQL查询不到新插入的数据。
执行
REFRESH TABLE dw_jck_xs_xjjbsj;
毫无效果,说明和缓存没有关系
2).发现文件存储特点
无意中,看到这个表的hdfs文件存储路径和其他的表不一样,其他的表,都是表名下面直接就是parquet文件,结果他却有子文件件,样式是 “HIVE_UNION_SUBDIR_*”
查找资料发现: 当Hive表数据存放在多级子目录时,Spark不能识别和读取到数据。
3).子文件夹出现原因
生成dw_jck_xs_xjjbsj表时,使用了如下sql写法
insert overwrite table dw_jck_xs_xjjbsj
select a,b,c from temp_a t1
union all
select a,b,c from temp_b t2
这样生成hdfs文件就会有子文件夹
5.解决方式
1). 方法1修改配置
优缺点: 这个配置就是让spark-sql放弃自己的缓存机制,使用hive的,虽然能用,但是放弃了spark-sql的优势,过于激进,不采用
-- 在spark-sql里执行
set spark.sql.hive.convertMetastoreOrc = false; -- 禁用orc格式spark的解析器,使用hive的
set spark.sql.hive.convertMetastoreParquet=false; -- 禁用parquet格式spark的解析器,使用hive的
set hive.mapred.supports.subdirectories=true; -- hvie支持子文件夹读取
set mapreduce.input.fileinputformat.input.dir.recursive=true; -- hvie支持子文件夹读取
2). 方法2修改脚本
制定sql编写规范,采用先把union all的结果写入临时表,再插入结果表
create temporary table temp_dw_jck_xs_xjjbsj as
select a,b,c from temp_a t1
union all
select a,b,c from temp_b t2
;
insert overwrite table dw_jck_xs_xjjbsj
select a,b,c from dw_jck_xs_xjjbsj
;
6.总结
最终项目上采用代价比较小的修改脚本的方法,并且把这个语法,制定在规范中。
标签:xs,hive,查询,SparkSQL,sql,Hive,dw,spark,xjjbsj From: https://blog.csdn.net/pengpenhhh/article/details/142755030