Spark加载S3端无压缩TSV文件时少量行全值归入首列的异常
Spark 加载S3存储TSV文件解析异常说明
问题基本情况
- 业务表包含
keyword、id、date三列,正常样例数据结构如下:
| keyword | id | date |
|---|---|---|
| apple | A1 | 2021-01-01 |
| apple | A2 | 2021-01-02 |
| apple | A3 | 2021-01-02 |
- 表以无压缩TSV格式存入S3,直接校验S3源文件的distinct日期值完全正确
- 使用指定加载函数读取时,十亿级总数据行里约0.002%的行出现解析异常:
- 所有列的内容全部被归入第一列,其余两列值为
null - 被合并进首列的内容顺序不保证与原行一致
- 最终解析完成后统计的distinct日期值,除原有有效日期外,额外多出
null值
- 所有列的内容全部被归入第一列,其余两列值为
- 初始排查时怀疑
inferSchema=true是异常诱因
现有加载代码逻辑
def load(s3Path: String): DataFrame = { sparkSession.read .format("com.databricks.spark.csv") .option("header", true) .option("maxCharsPerColumn", MAX_CHARS_PER_COLUMN) .option("delimiter", "\t") .option("inferSchema", true) .load(s3Path) }
问题根因
部分keyword字段的值带有未闭合的引号(例如值为"apple这类缺少收尾引号的内容)。
Spark CSV解析器默认会识别双引号作为字段边界标记,当读到以未闭合引号开头的内容时,会持续向后扫描直到匹配到下一个闭合引号,扫描过程中不会识别TSV的\t分隔符,直接将跨列、甚至跨行的全部内容归入第一列,剩余列默认赋值为null,这也是合并进首列的内容顺序与原行预期不一致的原因。
注:
inferSchema=true并非本次异常的诱因,该配置仅会在正式加载前额外扫描一轮数据完成类型推断,不会改变底层CSV解析器的字段拆分规则。
可参考的修复方向
- 调整读取配置:禁用解析器的引号识别逻辑,增加配置
.option("quote", "\u0000")(指定一个不会出现在业务数据中的不可见字符作为引号标记,相当于跳过引号解析流程,适配TSV无字段引号包裹的写入场景) - 数据预处理:写入S3前对业务字段做清洗,剔除或转义字段内多余的未闭合引号,从数据源层面避免解析歧义
- 优化加载逻辑:明确三列字段的实际类型,手动指定schema替代
inferSchema,可减少一轮全量数据扫描开销,提升加载效率
内容的提问来源于stack exchange,提问作者user3746406
相关产品推荐
相关产品推荐

