同一条sql语句 ,Spark Sql 和 hive shell 查询数据结果不一致。

背景:

hive表数据文件存储格式是parquet,存储在aliyun的oss存储中

问题描述:

saprk sql程序读取结果:

同一条sql语句 ,Spark Sql 和 hive shell 查询数据结果不一致。

hive shell 数据读取结果:

同一条sql语句 ,Spark Sql 和 hive shell 查询数据结果不一致。

hive shell查询的结果是完整的.

数据的写入

通过spark 程序执行的,存入代码如下所示:

udfService.register(map, df.sqlContext) 
df 
.withColumn("year", callUDF("getYear", col(tsName))) 
.withColumn("month", callUDF("getMonth", col(tsName))) 
.withColumn("day", callUDF("getDay", col(tsName))) .withColumn("hour",callUDF("getHour",col(tsName))) 
.repartition(col("year"), col("month"), col("day"), col("hour")) 
.write.partitionBy("year", "month", "day") 
.mode(SaveMode.Append) .format("parquet") 
.save(path) 
if (!fakeDataRdd.isEmpty()) 
{ ss.sql(s"MSCK REPAIR TABLE $hive_total_tableName") }

将数据以天时分分区,以parquet格式 存入oss(阿里云对象存储)的链接中.然后重构数据表,将oss的数据链接进hive中。

解决办法:

批处理程序启动时设置两个配置项为false

val ss = SparkSession 
.builder 
.appName(AppConfig.appName)
.config("spark.sql.crossJoin.enabled","true")
.config("spark.sql.hive.convertMetastoreParquet","false")
.config("spark.sql.hive.convertMetastoreOrc","false")
.enableHiveSupport() 
.getOrCreate()

spark.sql的配置项官方说明:https://spark.apache.org/docs/2.3.2/sql-programming-guide.html

spark.sql.hive.convertMetastoreParquet :

When reading from and writing to Hive metastore Parquet tables, Spark SQL will try to use its own Parquet support instead of Hive SerDe for better performance. This behavior is controlled by the spark.sql.hive.convertMetastoreParquet configuration, and is turned on by default.

spark.sql.hive.convertMetastoreOrc:

 

enables new ORC format to read/write Hive Tables.

问题产生原因

为了优化读取parquet格式文件,spark默认选择使用自己的解析方式读取数据,结果读出的数据就有问题。

我建表时的指定格式如下图所示:

同一条sql语句 ,Spark Sql 和 hive shell 查询数据结果不一致。

两种解析方式不同然后数据就不一样了,

所以将配置项spark.sql.hive.convertMetastoreParquet 改为false就行了