加快复制1000000个小文件的速度

奥莱·丹吉(Ole Tange)

我有百万4-20 KB文件的目录(可以产生类似的这样的文件:seq 10000 | gzip > a; seq 1000000 | parallel --bar 'head -c{=$_=int(rand()*16)+4=}k a > {}'

我需要复制该目录。但是似乎我必须对每个文件进行搜索,因此这需要花费相当长的时间。

有什么方法可以加快速度吗?

我目前在想,如果我可以获取这些文件所占用的磁盘块,则可以对它们进行排序,合并关闭的块(假定顺序读取通常比查找要快)并读取这些块,以便它们位于RAM中缓存(我有32 GB RAM),然后再进行复制。

但是,要使其正常工作,我需要一种方法来确定文件位于哪些块上。

我在磁性设备(即非SSD)上使用EXT4。

编辑:

这应该可行,但不能:

ls |
parallel -IOO --pipe "sudo parallel -j100 hdparm --fibmap {}'|tail -n +5'" |
sort -nk 2 | 
perl -ane 'if($u+10000 < $F[1]) { print "$l ",($u-$l),"\n"; $l=$F[1] } $u=$F[2]' |
sudo parallel --colsep ' ' dd if=/dev/sda1 skip={1} bs=512 count={2} '| cat >/dev/null'

在大文件上对其进行测试时,它不会缓存该文件。

编辑2:

这是一些基准。echo 3 >/proc/sys/vm/drop_caches在每次运行之间刷新缓存()。用进行的测量iostats -dkx 5

rsync -Hav foo/ bar/: 1800 KB/s
cp -a foo/ bar/: 3600 KB/s
cat sort-by-inode | parallel -j1 -X cp foo/{} bar/: 5000 KB/s
cat sort-by-inode | shuf | parallel -j1 -X cp foo/{} bar/: 3000 KB/s
cat sort-by-inode | shuf | parallel -j10 -X cp foo/{} bar/: 7000 KB/s
cat sort-by-inode | parallel -j10 -X cp foo/{} bar/: 8000 KB/s
cat sort-by-inode | parallel -j100 -X cp foo/{} bar/: 9000 KB/s
cat sort-by-inode | parallel -j500 -X cp foo/{} bar/: 10000 KB/s

那么我们可以从中学到什么呢?

看来按inode排序是个好主意。但是,似乎cp可以进一步并行化多个提升性能。值得强调的是,源foo/是磁盘,因此这打破了将I / O并行化为单个主轴不会加快I / O的神话:清晰并行地并一贯地加快此处的复制速度。

Maxschlepzig

假如说

  • 返回的条目readdir未按索引节点编号排序
  • 以inode顺序读取文件减少了查找操作的次数
  • 大多数文件的内容都在最初的8k分配中(ext4优化),这也应该产生较少的查找操作

您可以尝试通过按inode顺序复制文件来加快复制速度。

那意味着使用这样的东西:

$ cd /mnt/src
$ ls -U -i | sort -k1,1 -n | cut -d' ' -f2- > ~/clist
$ xargs cp -t /mnt2/dst < ~/clist

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

Related 相关文章

热门标签

归档