Spark生产案例分享:Hive分区表修改字段名后Spark查询空值?
1.企业案例背景
客户最新产品文档里要求变更字段名,数仓开发小伙伴按照客户爸爸的要求使用Hive标准语法修改了列名;比如将字段FCD60改为FLN90。
现象描述:表是分区ORC表,Spark版本2.4x。
修改历史有历史分区数据的表的字段名后,导致spark-sql读取hive表历史分区时,被修改的字段FLN90读取到的都是null值。但是读取新的分区数据时,不受影响,被修改的字段值可以正常读取;
2.问题排查与解决
排查测试,换个其他格式的表如textfile发现没有这种问题。于是查询spark官网,搜索关于orc表这块的Jira
发现是可能是由于spark.sql.hive.convertMetastoreOrc参数默认值的变化造成的,Spark 2.4 以后, Spark将采用自身的 SerDe 而非采用 Hive 的SerDe 处理 Hive 的 ORC 数据表(SerDe是Serialize/Deserilize的简称,目的是用于序列化和反序列化)
具体源代码在于: HiveStrategies.scala中 RelationConversions 类中, 可以看到根据配置不同, 对于 ORC 文件采用两种不同的处理方式
其中采用 org.apache.spark.sql.execution.datasources.orc.OrcFileFormat 会导致如上问题.
尖叫总结:
在 Spark 2.3 以后, Spark 增加 spark.sql.hive.convertMetastoreOrc 参数, 设定 ORC 文件使用采用向量化 Reader, 但是会引申由于 Spark SQL 无法与 Hive SQL 采用同一 SerDe 从而对 Parquet/Hive 数据表产生处理上的不同, 因此需要限定如下参数从而让 Spark 使用 Hive 的SerDe.
这就是一个很好的spark生产中遇到的案例,有应用场景有解决方案,既体现了你扎实的spark功底,又体现了你生产中rouble shooting的能力。小白面试时讲讲这个案例,不比你背的八股文更加真实和加分哈;
