在线支持
在线支持
微信支持
微信支持
【知识分享】小文件相关的问题以及应该怎么处理
2022-10-27 19:42:53
164次阅读
0个评论

问题背景

很多客⼾在⽣产环境都会遇到⼩⽂件问题,⼩⽂件可能来⾃于上游系统,可能来⾃于书写不当的sql,也可能是错误数据导致join ⽣成⼤量⼩⽂件。 ⽤⼾侧观察到的现象就是,性能下降,任务报错,甚⾄executor lost。

问题分析

⼩⽂件问题隐患:

1. 导致map 任务⾮常多,从而性能下降;

2. ⼩⽂件过多,可能会影响到后续reduce任务数量暴增,从⽽导致出现task 超过10w的情况,这时候引擎会出于⾃我保护会报错; 

3. ⼩⽂件如果⾮常⼩,在进⾏automerge后,还可能导致executor端,每个task需要读太多⼩⽂件,从⽽会在⼀个task中new 过多DFSClient,DFSInputStream,Path,JobConf对象等,导致 executor端内存和gc 压⼒很⼤,甚⾄executor lost。


排查思路

⼀般来说,⼀个任务是由⼏个步骤组成的,⽽⼩⽂件的产⽣也来⾃任务的各个流程和步骤: 

上游 => 本地⽂件系统 => HDFS => Map => Reduce => FileSink 

所以解决⼩⽂件问题就是从上⾯步骤中⼊⼿,并且解决⼩⽂件的隐患越早越好,跟过滤下推⼀样,能尽早做的过滤条件⼀定是尽早过滤。 能在本地⽂件系统解决的问题,没必要放到HDFS上解决,因为HDFS本⾝就不适合存储⼤量⼩⽂件,⼩⽂件过多会导致namenode元数据特别⼤, 占⽤太多内存,严重影响HDFS的性能。


解决方案


1. 上游系统改进
2. linux⽂件系统合并
3. hdfs 合并:hdfs dfs -appendToFile a.txt b.txt c.txt hdfs://${namenode}/data/all.txt
4. concatenate 命令,⾃动合并orc ⼩⽂件

5. maptask阶段合并:automerge 


Automerge⽤法及注意事项:https://community.transwarp.cn/thread?topicId=250

改进partition automerge:https://community.transwarp.cn/thread?topicId=251


6. reduce 阶段合并:reduce tasks 设置,mapred.reduce.tasks,如果没有sql本来没有reduce,可以加上:distribute by rand();

7. filesink合并:


⼩⽂件合并改进:https://community.transwarp.cn/thread?topicId=253

⼩⽂件合并设计实现版本:https://community.transwarp.cn/thread?topicId=252

操作实例

某⽤⼾上游应⽤产⽣了57000 个⼩⽂件,每个⽂件⼀⾏数据。创建text 外表后,执⾏任务报了task 超过10w。 第⼀反应先⾛automerge,开启automerge后,数据本地合并后⼤概合并了出了不到10 个task,然后就把executor 跑lost了。 

问题是每个任务需要读的⽂件太多了,⼀个task中连续new DFSClient,DFSInputStream,Path,JobConf 等对象,导致gc压⼒太⼤,最后executor lost。 

最终解决⽅案是: 

1. 尽量在本地⽂件系统上合并 

2. 本地⽂件系统如果不能合并,在hdfs 上使⽤append file 合并 

3. 如果不能在local filesystem或者hdfs合并,考虑创建中间表,通过reduce task + distribute by来降低⽂件数量

收藏 0 0

登录 后评论。没有帐号? 注册 一个。

admin

官方人员
  • 0 回答
  • 0 粉丝
  • 0 关注