Ole*_*nge 12 filesystems cache
我有百万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'
Run Code Online (Sandbox Code Playgroud)
在大文件上测试时,它不会缓存文件。
编辑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
Run Code Online (Sandbox Code Playgroud)
那么我们可以从中学到什么呢?
似乎按 inode 排序是个好主意。但它似乎cp
进一步并行化了多个提升性能。值得强调的是,源foo/
是一个磁盘,所以这打破了将 I/O 并行到单个主轴不会加速 I/O 的神话:这里的并行化清晰且一致地加速了复制。
max*_*zig 10
假如说
readdir
未按 inode 编号排序您可以尝试通过按 inode 顺序复制文件来加快复制速度。
这意味着使用这样的东西:
$ cd /mnt/src
$ ls -U -i | sort -k1,1 -n | cut -d' ' -f2- > ~/clist
$ xargs cp -t /mnt2/dst < ~/clist
Run Code Online (Sandbox Code Playgroud)
GNU tar
- 按照pax
传统 - 自行处理硬链接。
cd "$srcdir" ; tar --hard-dereference -cf - ./* |
tar -C"${tgtdir}" -vxf -
Run Code Online (Sandbox Code Playgroud)
这样你就只有两个tar
进程,你不需要cp
一遍又一遍地调用。