1. 问题背景与现象
在实时数据湖架构中,Flink + Hudi 的组合已经成为行业标配。我们团队在生产环境中部署了一套完整的 Kafka+Flink+Hudi+Spark 数据处理链路,用于支撑业务实时分析和报表生成。这套架构已经稳定运行了相当长的时间,直到某天凌晨突然触发了告警风暴。
当时的情况是:下游Spark批处理任务突然失败,同时上游Flink实时写入作业在短时间内频繁重启。这种上下游同时告警的情况立即引起了我们的警觉,因为这意味着问题可能出在核心的数据写入环节。
通过查看Spark任务的错误日志,我们发现了关键报错信息:
code复制java.lang.RuntimeException: hdfs://xx/../41307bff-173e-497a-a1c4-c3bf58f9337c-2_3-4-9_20241211103654416.parquet is not a Parquet file (too small length: 0)
这个错误直指问题的核心 - Spark任务在尝试读取一个0字节的Parquet文件时失败了。这显然不是正常的业务数据文件,而是一个损坏的文件占位符。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 问题排查过程
2.1 下游Spark任务排查
我们首先对Spark任务进行了详细排查:
- 通过HDFS命令检查问题文件:
bash复制hdfs dfs -ls /path/to/problem/file.parquet
hdfs dfs -du /path/to/problem/file.parquet
确认该文件确实大小为0字节,这解释了为什么Spark无法将其识别为有效的Parquet文件。
-
检查文件创建时间与作业失败时间的对应关系,发现文件创建时间与Flink作业最近一次重启时间高度吻合。
-
排查Hudi表的元数据(.hoodie目录),发现该文件没有被任何commit引用,属于"孤儿文件"。
2.2 上游Flink任务排查
转向Flink作业的排查后,我们在TaskManager日志中发现了更多线索:
-
大量
HoodieClusteringException和FileNotFoundException错误,指向同一个0字节文件。 -
错误发生的时间点与chec
