Spark 2.4.7读取JSON时数字被识别为StringType问题排查
问题分析与解决方案
核心问题
Spark 2.4.7 Java应用加载多行JSON时,data.key.field字段值为数字却被识别为StringType,但本地Spark Shell测试正常。
可能原因及解决办法
1. 生产数据存在混合类型(最常见)
Spark的JSON自动类型推断基于采样数据:如果生产环境的JSON文件中,data.key.field字段同时存在数字(如7569)和带引号的字符串数字(如"7569"),Spark会将该字段推断为StringType;而你本地测试用的是单一类型的干净数据,所以Shell中识别正常。
- 解决:
- 检查所有JSON记录的
data.key.field字段,统一格式(全部改为数字类型,去掉引号); - 手动指定Schema强制类型(最可靠,不受数据波动影响),示例代码:
import org.apache.spark.sql.types.DataTypes; import org.apache.spark.sql.types.StructType; // 定义精确的Schema StructType jsonSchema = new StructType() .add("first", new StructType() .add("id", DataTypes.StringType) .add("name", DataTypes.StringType) .add("type", DataTypes.LongType)) .add("something", DataTypes.StringType) .add("data", new StructType() .add("key", new StructType() .add("field", DataTypes.LongType) // 强制指定为LongType .add("temp", DataTypes.StringType))); // 加载时指定Schema Dataset<Row> df = sparkSession().read() .option("multiline", true) .schema(jsonSchema) .format("json") .load(path_of_json);
- 检查所有JSON记录的
2. 读取路径包含多文件
如果path_of_json指向的是一个目录(而非单个文件),目录中某部分JSON文件的data.key.field是字符串类型,会导致全局推断为StringType;而本地Shell可能只加载了单个正确的文件。
- 解决:检查路径下所有JSON文件的字段格式,或指定单个文件测试验证。
3. Spark配置差异
虽然版本都是2.4.7,但Java应用和Spark Shell的配置可能存在差异,比如:
spark.sql.json.parser.lib:Spark 2.4支持jackson和databricks两种解析器,不同解析器的类型推断逻辑可能有细微差别;spark.sql.caseSensitive:大小写敏感设置如果不一致,可能导致字段匹配异常(但此场景下概率较低)。解决:对比Java应用与Shell的Spark配置,确保关键配置一致,比如在Java代码中显式设置:
sparkSession().conf().set("spark.sql.json.parser.lib", "jackson");
内容的提问来源于stack exchange,提问作者Prateek Gautam
相关产品推荐
相关产品推荐

