为何rsync可以快速删除400000文件?

背景 Quora上一篇文章★How can someone rapidly delete 400,000 files?提到经过rsync可以快速删除大量文件,以后在Linux技巧:一次删除一百万个文件的最快方法这篇文章里作了一个详细的评测,对于rm/find/rsync等诸多方法的性能作了对比。es6

对于出现性能的差别,应该属于预料中的结果。为了验证这个现象,我模拟了Quora原提问的要求,建立了40万个文件,分别用rm和rsync进行删除操做,对syscall作统计。为了简化条件,这写文件所有是空文件(使用包含内容的文件对结果不会形成明显差别,有兴趣能够重试一下)。api

统计syscall使用了dtruss工具,这是MacOSX上提供的syscall调试工具,基于DTrace。Linux上可使用SystemTap来代替。session

验证测试步骤 第一步,建立测试文件并发

mkdir tmp/; seq 1 400000 | xargs -I{} touch tmp/file_{} 建立的目录文件大小约为13M。这个大小指的是目录文件,不包含目录中文件,要注意。socket

$ ls -dl tmp/ drwxr-xr-x 56513 lax wheel 13062562 6 13 16:18 tmp-test-rsync 第二步,使用dtruss执行rm命令测试工具

$sudo dtruss -c 'rm -rf tmp-test-rm/'性能

CALL COUNT __mac_syscall 1 audit_session_self 1 bsdthread_register 1 exit 1 fstatfs64 1 getaudit_addr 1 getegid 1 rmdir 1 shared_region_check_np 1 thread_selfid 1 __sysctl 2 close 2 close_nocancel 2 csops 2 getpid 2 ioctl 2 issetugid 2 open 2 open_nocancel 2 pread 2 geteuid 3 fchdir 4 mprotect 8 stat64 34 mmap 93 munmap 184 madvise 205 getdirentries64 2659 lstat64 311901 unlink 400000 第三步,使用dtruss执行rsync命令测试测试

$sudo dtruss -c 'rsync -a --delete empty/ tmp/'ui

CALL COUNT __mac_syscall 1 __pthread_canceled 1 audit_session_self 1 bsdthread_register 1 exit 1 fcntl_nocancel 1 fork 1 fstatfs64 1 getaudit_addr 1 getegid 1 getrlimit 1 getuid 1 ioctl 1 lstat64 1 shared_region_check_np 1 shm_open 1 sigprocmask 1 sigreturn 1 thread_selfid 1 umask 1 __sysctl 2 chdir 2 csops 2 getdirentries64 2 getpid 2 lseek 2 pread 2 socketpair 2 fstat64 3 munmap 3 open_nocancel 3 close 4 close_nocancel 4 geteuid 4 issetugid 4 open 4 wait4 6 read_nocancel 7 write 7 mprotect 8 read 10 sigaction 10 fcntl 11 mmap 13 select 21 stat64 35 现象分析 rm rm命令大量调用了lstat64和unlink,能够推测删除每一个文件前都从文件系统中作过一次lstat操做。 lstat64的次数低于文件总数,还有另外的缘由,以后会在另外一篇文章中说明。 getdirentries64这个调用比较关键。 过程:正式删除工做的第一阶段,须要经过getdirentries64调用,分批读取目录(每次大约为4K),在内存中创建rm的文件列表;第二阶段,lstat64肯定全部文件的状态;第三阶段,经过unlink执行实际删除。这三个阶段都有比较多的系统调用和文件系统操做。 rsync rsync所作的系统调用不多。 没有针对单个文件作lstat和unlink操做。 命令执行前期,rsync开启了一片共享内存,经过mmap方式加载目录信息。 只作目录同步,不须要针对单个文件作unlink。 另外,在其余人的评测里,rm的上下文切换比较多,会形成System CPU占用较多——对于文件系统的操做,简单增长并发数并不总能提高操做速度。调试

总结 把文件系统的目录与书籍的目录作类比,rm删除内容时,将目录的每个条目逐个删除(unlink),须要循环重复操做不少次;rsync删除内容时,创建好新的空目录,替换掉老目录,基本没开销。

结论:频繁作减法不如直接从头来过。

相关文章
相关标签/搜索