Mal*_*ous 17 linux io cache cifs
概括
如何将 Linux 配置为同时从本地磁盘/文件系统读取并写入网络共享,而不是在没有数据通过网络时读取,然后在本地磁盘处于传输状态时通过网络发送该数据闲置的?
同时读取和写入要快得多,而不是只执行一个操作,然后以交替方式执行另一个操作。
细节
我正在将大量数据从 Linux 机器上的本地磁盘移动到 NAS 设备。
我rsync
用来基本上复制/srv/data
到/mnt/nas
,这是一个 CIFS 挂载。
它开始很好,读取速度为 100MB/秒,写入 NAS 速度为 100MB/秒(千兆网络的限制),读取和写入同时进行。
但是现在,几个小时后,我发现它正在从本地磁盘读取,然后在写入 NAS 时停止读取,然后当没有更多数据要写入 NAS 时,它恢复从磁盘读取再次。读取磁盘时网络空闲,使用网络时磁盘空闲。
不用说,读取 200MB 然后写入 200MB 比同时读取和写入 200MB 花费的时间要长得多。
如何配置内核,使其坚持早期同时读取和写入的行为,而不是在读取和写入之间交替,一次只执行一个操作?
一些观察:当本地磁盘以 100+MB/秒的速度读取时,一切似乎都并行发生,但是一旦磁盘变慢(由于某种原因,现在似乎只有 20MB/秒),这就是读取/写入的时间切换似乎发生了。
我也sync
可以每隔几秒钟手动运行一次以使写入与读取并行发生(尽管显然速度降低了)但是放入sync
一个while
循环中使其每五秒运行一次似乎不是正确的解决方案......
内核似乎缓存了大约 1GB 的数据,然后尽可能快地通过网络将其写出 - 这很好 - 我只是不明白为什么在通过网络发送数据时需要停止读取慢速磁盘网络。
Mal*_*ous 27
经过更多调查,看起来这个问题与内核的相关性较少,而更多地rsync
与 CIFS 的交互方式有关。
据我所知,发生的事情是,当rsync
关闭目标文件时,CIFS(可能还有任何网络文件系统)确保文件在close
系统调用返回之前完全刷新并写入远程磁盘。这是为了确保任何应用程序一旦关闭操作成功完成,文件已完全保存,并且不存在可能导致数据丢失的任何进一步错误的风险。
如果不这样做,那么应用程序可能会关闭文件,认为保存操作成功退出,然后(可能是由于网络问题)最终无法写入数据,但到那时应用程序对此做任何事情都为时已晚,例如询问用户是否要将文件保存在其他地方。
这个要求意味着每次rsync
完成复制文件时,整个磁盘缓冲区必须通过网络清空,然后rsync
才能继续读取下一个文件。
解决方法是使用cache=none
禁用此功能的选项挂载 CIFS 共享,并使所有 I/O 直接进入服务器。这消除了问题并允许并行执行读取和写入,但是该解决方案的缺点是性能稍低。就我而言,网络传输速度从 110MB/秒下降到 80MB/秒。
这可能意味着如果您要复制大文件,交替读/写行为可能会更好地提高性能。对于许多较小的文件,禁用缓存将导致每次关闭文件时缓存刷新次数减少,因此性能可能会提高。
它似乎rsync
需要一个选项来关闭另一个线程中的文件句柄,这样它就可以在最后一个文件仍在刷新时开始读取下一个文件。
编辑:我已经确认这cache=none
在传输大量小文件(将其从 10MB/秒提高到 80MB/秒)时绝对有帮助,但在传输大文件(1GB+)时cache=none
,传输速度从 110MB/秒下降到相同的 80MB/秒。这表明从许多小文件传输的缓慢与源磁盘查找无关,而更多的是从所有小文件中刷新了如此多的缓存。