SparkSQL与Hive查询不一致问题

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.总结

最终项目上采用代价比较小的修改脚本的方法,并且把这个语法,制定在规范中。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鹏说大数据

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值