这是个人原创的我的心得,如有纰漏,多多指教
更多内容能够访问 个人博客
公司有台服务器产生太多临时文件,同事在删除文件的时候,说使用 rsync 会更快一些,使用 rm 可能会把机器搞挂,还引用网上一篇文章说 node
"rsync所作的系统调用不多:没有针对单个文件作lstat和unlink操做。命令执行前期,rsync开启了一片共享内存,经过mmap方式加载目录信息。只作目录同步,不须要针对单个文件作unlink"缓存
我对此抱有好奇与怀疑,在个人Linux知识中,从 Linux 中删除文件,须要是文件的硬链接数n_link归零、进程正在打开该文件的数n_count归零,才能够触发文件系统对 inode 与对应磁盘块的回收,实现删除操做。这是金科玉言,完全删除文件的系统调用必然用到 unlink 与 close。性能优化
对于网传的理论,我在互联网上仔细搜索,发现太多转载的雷同的文章,却没有精华文章对上面的话作详细的解释。我决定本身研究下服务器
网传这样的方法socket
例如删除某目录下一万个以上小文件,使用 rm * -rf
,既有操做上的风险,又耗时。性能
建议使用 rsync
测试
mkdir /tmp/blank_dir rsync --delete-before -a -H -v /tmp/blank_dir/ target_dir
/
rsync 选项说明:
--delete-before 接收者在传输以前进行删除操做
--progress 在传输时显示传输过程
--a 归档模式,表示以递归方式传输文件,并保持全部文件属性
--H 保持硬链接的文件
--v 详细输出模式
--stats 给出某些文件的传输状态优化
从根本入手,直接查看系统调用状况,因而动手测试ui
实验环境:Linux Arch 4.19code
建立必定数量的空白文件,分别使用 rm 与 rsync 删除,并使用 strace -c
统计系统调用,须要额外注意的是 rsync 在本地使用了三个进程(generator, sender, receiver),因此须要 -f
选项告诉 strace 同时跟踪全部fork和vfork出来的进程。(因为 strace 输出的信息太多,为了阅读体验,打印详情在附录)
第一次,建立10个文件,分别删除,查看统计输出
查看 rm 的系统调用,耗时0.000000,总次数62
for i in $(seq 10); do touch tmp_$i;done strace -c rm * -rf
查看 rsync 的系统调用,总耗时0.008647,总次数365
for i in $(seq 10); do touch tmp_$i;done strace -c -f rsync --delete -a -H ../blank_dir/ ./
由于10个文件的删除,几乎看不到时间,我第二次测试,删除一万个文件,结果:
rm 的系统调用,总耗时0.201209,总次数20063
rsync 的系统调用,总耗时0.625734,总次数20374
从这个结果来看,彷佛 rsync 比 rm 要慢,这里有我使用 strace -f
统计 rsync 三个进程总耗时的缘由,改用使用 time 命令来计时,删除一万个文件以上,rsync 确实是比 rm 快上一些,那是由于我电脑cpu在三个以上,三个进程的rsync固然快一些
网传的 "删除多个文件,rsync 比 rm 快" 的方法,我认为不必定准确,理由以下:
我想,多是有人对 rsync 的评测不严谨,在本地删除文件时,漏了检查 rsync 的两个进程的系统调用,才致使的以讹传讹。
第一次,建立10个文件,分别删除,查看统计输出
使用 rm :
for i in $(seq 10); do touch tmp_$i;done strace -c rm * -rf % time seconds usecs/call calls errors syscall ------ ----------- ----------- --------- --------- ---------------- 0.00 0.000000 0 4 read 0.00 0.000000 0 6 close 0.00 0.000000 0 3 fstat 0.00 0.000000 0 1 lstat 0.00 0.000000 0 4 1 lseek 0.00 0.000000 0 8 mmap 0.00 0.000000 0 4 mprotect 0.00 0.000000 0 1 munmap 0.00 0.000000 0 3 brk 0.00 0.000000 0 1 ioctl 0.00 0.000000 0 1 1 access 0.00 0.000000 0 1 execve 0.00 0.000000 0 2 1 arch_prctl 0.00 0.000000 0 3 openat 0.00 0.000000 0 10 newfstatat 0.00 0.000000 0 10 unlinkat ------ ----------- ----------- --------- --------- ---------------- 100.00 0.000000 62 3 total
使用 rsync, strace 的输出中能够看到 rsync fork 出两个子进程
for i in $(seq 10); do touch tmp_$i;done strace -c -f rsync --delete -a -H ../blank_dir/ ./ strace: Process 17207 attached strace: Process 17208 attached % time seconds usecs/call calls errors syscall ------ ----------- ----------- --------- --------- ---------------- 61.13 0.005286 587 9 5 wait4 5.39 0.000466 46 10 unlink 3.80 0.000329 9 34 1 select 3.59 0.000310 8 37 mmap 3.27 0.000283 5 51 read 2.88 0.000249 62 4 getdents64 2.68 0.000232 29 8 munmap 2.43 0.000210 5 37 close 2.36 0.000204 8 23 4 openat 2.32 0.000201 10 19 write 2.32 0.000201 14 14 lstat 1.28 0.000111 5 19 fstat 1.14 0.000099 12 8 8 connect 0.83 0.000072 9 8 socket 0.73 0.000063 31 2 utimensat 0.67 0.000058 3 17 fcntl 0.49 0.000042 14 3 socketpair 0.45 0.000039 5 7 lseek 0.40 0.000035 17 2 2 nanosleep 0.38 0.000033 3 11 mprotect 0.37 0.000032 2 12 rt_sigaction 0.24 0.000021 10 2 1 stat 0.23 0.000020 10 2 2 rt_sigreturn 0.22 0.000019 9 2 chdir 0.22 0.000019 9 2 getgroups 0.15 0.000013 6 2 clone 0.00 0.000000 0 6 brk 0.00 0.000000 0 1 rt_sigprocmask 0.00 0.000000 0 1 1 access 0.00 0.000000 0 2 dup2 0.00 0.000000 0 1 getpid 0.00 0.000000 0 1 execve 0.00 0.000000 0 1 kill 0.00 0.000000 0 1 getcwd 0.00 0.000000 0 2 umask 0.00 0.000000 0 1 geteuid 0.00 0.000000 0 1 getegid 0.00 0.000000 0 2 1 arch_prctl ------ ----------- ----------- --------- --------- ---------------- 100.00 0.008647 365 25 total
删除 10 个文件,看起来 rsync 的系统调用次数比 rm 要多,我决定加大文件数量测试
第二次测试,删除一万个文件
for i in $(seq 10000); do touch tmp_$i;done strace -c rm * -rf % time seconds usecs/call calls errors syscall ------ ----------- ----------- --------- --------- ---------------- 70.08 0.141015 14 10000 unlinkat 29.67 0.059692 5 10000 newfstatat 0.08 0.000158 6 24 brk 0.04 0.000083 10 8 mmap 0.02 0.000048 12 4 mprotect 0.02 0.000036 12 3 openat 0.02 0.000035 5 6 close 0.01 0.000025 6 4 read 0.01 0.000024 24 1 munmap 0.01 0.000023 5 4 1 lseek 0.01 0.000019 6 3 fstat 0.01 0.000013 6 2 1 arch_prctl 0.01 0.000011 11 1 1 access 0.00 0.000010 10 1 execve 0.00 0.000009 9 1 ioctl 0.00 0.000008 8 1 lstat ------ ----------- ----------- --------- --------- ---------------- 100.00 0.201209 20063 3 total
strace -c -f rsync --delete -a -H ../blank_dir/ ./ strace: Process 16414 attached strace: Process 16415 attached % time seconds usecs/call calls errors syscall ------ ----------- ----------- --------- --------- ---------------- 61.75 0.386408 42934 9 5 wait4 19.18 0.120021 12 10000 unlink 15.97 0.099912 9 10004 lstat 2.21 0.013827 1063 13 getdents64 0.14 0.000860 20 41 mmap 0.12 0.000755 32 23 4 openat 0.10 0.000604 11 54 read 0.08 0.000479 12 37 close 0.07 0.000422 35 12 munmap 0.05 0.000338 30 11 mprotect 0.05 0.000284 35 8 8 connect 0.04 0.000251 13 19 fstat 0.04 0.000239 19 12 rt_sigaction 0.04 0.000236 5 40 1 select 0.03 0.000192 24 8 socket 0.03 0.000157 7 22 write 0.02 0.000156 26 6 brk 0.01 0.000084 4 17 fcntl 0.01 0.000079 39 2 utimensat 0.01 0.000078 11 7 lseek 0.01 0.000060 20 3 socketpair 0.01 0.000041 41 1 getcwd 0.01 0.000036 18 2 umask 0.00 0.000027 27 1 rt_sigprocmask 0.00 0.000026 13 2 chdir 0.00 0.000025 25 1 1 access 0.00 0.000022 11 2 1 stat 0.00 0.000022 22 1 geteuid 0.00 0.000021 10 2 1 arch_prctl 0.00 0.000020 20 1 execve 0.00 0.000019 19 1 getegid 0.00 0.000014 7 2 2 nanosleep 0.00 0.000010 5 2 clone 0.00 0.000009 4 2 2 rt_sigreturn 0.00 0.000000 0 2 dup2 0.00 0.000000 0 1 getpid 0.00 0.000000 0 1 kill 0.00 0.000000 0 2 getgroups ------ ----------- ----------- --------- --------- ---------------- 100.00 0.625734 20374 25 total