爲何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刪除內容時,創建好新的空目錄,替換掉老目錄,基本沒開銷。

結論:頻繁作減法不如直接從頭來過。

相關文章
相關標籤/搜索