Pig加载大型CSV文件出现数据截断问题
这种单个大文件加载行数不足、拆分后却能正常加载的情况,大概率和多行记录解析逻辑、文件格式一致性或者内存限制有关,结合你使用的CSVExcelStorage参数,我给你拆解下可能的原因和对应的排查方法:
1. 多行记录解析异常(最可能的原因)
你设置了YES_MULTILINE参数,它允许字段内包含换行,但要求这类带换行的字段必须用引号包裹。如果你的大CSV里存在字段内有换行却未加引号的情况,Pig在解析大文件时,会把后续的行错误地合并到当前字段中,直接导致统计的总记录数大幅减少。而拆分成小文件时,这类跨多行的记录刚好被限制在单个小文件内,解析逻辑能正常收尾,所以行数统计正确。
排查&解决:
- 用文本编辑器打开大文件,搜索那些没有被引号包裹的换行符;
- 如果确实存在这类情况,要么给包含换行的字段加上引号,要么如果你的数据其实没有多行字段,直接把
YES_MULTILINE改成NO_MULTILINE再尝试加载。
2. 换行符格式不一致
你指定了UNIX换行格式,意味着Pig只会把\n当作行结束符。如果大文件中混合了Windows格式的\r\n,或者存在其他非标准换行符,会导致Pig误判行边界,部分行被合并或直接忽略。而拆分后的小文件可能在拆分过程中被统一了换行格式,所以解析正常。
排查&解决:
- 用
cat -A your_file.csv查看文件的换行符(UNIX换行显示为$,Windows换行显示为^M$); - 如果有混合换行,用
dos2unix工具把文件转换成纯UNIX格式后再加载。
3. 单个文件加载时的内存限制
处理超大文件时,Pig的Map任务内存不足,可能导致解析过程中部分数据未被处理就提前终止。拆分后的小文件单个Map任务负载低,内存足够支撑完整解析,所以能加载全部行数。
排查&解决:
- 调整Pig的内存参数,比如在运行脚本前执行:
数值可以根据你的集群资源调整,之后重新运行加载大文件的脚本。export PIG_MAPREDUCE_MEMORY_MB=4096
4. 文件损坏或特殊字符干扰
大文件可能存在隐藏的特殊字符(比如NULL字符、非打印ASCII字符),导致Pig的解析器在某个位置中断,后续行无法被读取。拆分后的小文件刚好避开了这些损坏的位置,所以能正常加载。
排查&解决:
- 用
grep -n "\x00" your_file.csv查找文件中的NULL字符,如果有,清除这些字符后再尝试; - 用
md5sum校验大文件和拆分后合并的文件是否一致,确保拆分过程中没有数据丢失。
额外测试建议
你可以先尝试去掉SKIP_INPUT_HEADER参数加载大文件,看看总记录数是否为50001(原5万行数据+1行表头),如果是,说明大文件中没有被误判的重复表头;另外,也可以用Pig默认的PigStorage(',')加载大文件,如果行数正确,那问题大概率出在CSVExcelStorage的多行解析逻辑上。
内容的提问来源于stack exchange,提问作者Anne Marie

