這是個人原創的我的心得,如有紕漏,多多指教
更多內容能夠訪問 個人博客
公司有臺服務器產生太多臨時文件,同事在刪除文件的時候,說使用 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