Linux反复写入大量文件,速度越来越慢

2021-08-28  本文已影响0人  Caucher

最近在项目实践过程中,设计了一个算法,算法每次要向同一个目录写入大量文件(有大有小),数量大约在5万多。

在运行实验的过程中,出现了一个诡异的现象:

  1. 首次运行,运行时间较好(1.5min左右);
  2. 删除运行结果,再次运行,运行时间有明显退化(5~10min左右);
  3. 之后再删除结果,反复运行,几乎一次比一次慢。

已经确认每次运行时环境是一样的,代码没有改动,数据没有变化。除此之外,还有一个更诡异的现象:

由于源数据集比较大(10GB),需要分多次load到内存中,因此对输出文件需要通过append的模式不断写入。我起初以为是append导致的问题,但是即使改成Write(覆盖写)模式也无济于事。

从监测数据来看,第一次读取是非常快速的(5s左右),主要限速步在写文件。
而从第二次开始,读取速度也变得不稳定,有时可能到30s这个水平。

基于这一点观察,我想到了linux inode分配的问题,linux每个文件都要一个inode来作为索引块,而大量文件在操作系统层面就要新分配大量的inode,这个过程也是要有耗时的。
同时要注意到由于inode数量也非常多,要查询也需要有相应的索引结构。

在我们第一次写入时,就分配了大量的inode,给了文件系统较大压力。此时即使程序已经运行完毕,文件系统可能也还在调整索引结构。而在此时,我们又将生成的大量文件删除了,如此操作,可能会让文件系统承载的压力非常大,inode分配混乱,最终导致服务能力下降。

考虑到这一层,我将原先写入所有文件的数据写入一个大文件,除此之外什么都不变 ,发现每一次的运行时间都变得非常稳定,不再出现之前的问题。也就是说,在设计的时候要避免生成大量的小文件,至少在unix-like系统中要这样。

另外补充一点,打开文件也是一个比较重的IO操作,在优化中,要避免反复打开文件。

上一篇 下一篇

猜你喜欢

热点阅读