Mengapa menghapus file dengan nama sangat lambat dan juga sangat cepat?

11

Faux pas: Metode "cepat" yang saya sebutkan di bawah, tidak 60 kali lebih cepat daripada yang lambat. Ini 30 kali lebih cepat. Saya akan menyalahkan kesalahan pada jam (3:00 bukan waktu terbaik saya hari untuk berpikir jernih :) ..

Pembaruan: Saya telah menambahkan ringkasan waktu pengujian (di bawah).
Tampaknya ada dua masalah yang terlibat dengan faktor kecepatan:

  • Pilihan perintah yang digunakan (Perbandingan waktu ditunjukkan di bawah ini)
  • Sifat sejumlah besar file dalam direktori ... Tampaknya "besar itu buruk". Hal-hal menjadi lambat secara tidak proporsional karena jumlahnya meningkat ..

Semua tes telah dilakukan dengan 1 juta file.
(waktu nyata, pengguna, dan sistem ada dalam skrip pengujian)
Skrip pengujian dapat ditemukan di paste.ubuntu.com

#
# 1 million files           
# ===============
#
#  |time   |new dir   |Files added in  ASCENDING order  
#  +----   +-------   +------------------------------------------------- 
#   real    01m 33s    Add files only (ASCENDING order) ...just for ref.
#   real    02m 04s    Add files, and make 'rm' source (ASCENDING order) 
#                      Add files, and make 'rm' source (DESCENDING order) 
#   real    00m 01s    Count of filenames
#   real    00m 01s    List of filenames, one per line
#   ----    -------    ------
#   real    01m 34s    'rm -rf dir'
#   real    01m 33s    'rm filename' via rm1000filesPerCall   (1000 files per 'rm' call)
#   real    01m 40s    'rm filename' via  ASCENDING algorithm (1000 files per 'rm' call)
#   real    01m 46s    'rm filename' via DESCENDING algorithm (1000 files per 'rm' call)
#   real    21m 14s    'rm -r dir'
#   real    21m 27s    'find  dir -name "hello*" -print0 | xargs -0 -n 1000 rm'
#   real    21m 56s    'find  dir -name "hello*" -delete'
#   real    23m 09s    'find  dir -name "hello*" -print0 | xargs -0 -P 0 rm'
#   real    39m 44s    'rm filename' (one file per rm call) ASCENDING
#   real    47m 26s    'rm filename' (one file per rm call) UNSORTED
#                                                       

Saya baru-baru ini membuat dan menghapus 10 juta file tes kosong. Menghapus file berdasarkan nama berdasarkan nama (yaitu rm filename), saya menemukan cara yang sulit bahwa ada perbedaan waktu yang sangat besar antara 2 metode yang berbeda ...

Kedua metode menggunakan rm filenameperintah yang sama persis .

Pembaruan: ternyata, perintahnya tidak persis sama ... Salah satunya mengirim 1000 nama file sekaligus ke 'rm' ... Itu adalah masalah perluasan-penahan shell di mana saya pikir setiap nama file ditulis ke file feeder pada barisnya sendiri, tetapi sebenarnya itu 1000 per baris

Nama file diberikan melalui 'file pengumpan' ke dalam satu while readlingkaran ..
File pengumpan adalah output dari ls -1 -f
Metode ini identik dalam semua pemanggilan kembali, kecuali untuk satu hal:

  • yang lambat metode menggunakan file pengumpan disortir langsung darils -1 -f
  • yang cepat metode menggunakan versi diurutkan dari file disortir sama

Saya tidak yakin apakah pengurutan masalah ini di sini, atau mungkin file pengumpan yang disortir kebetulan cocok dengan urutan di mana file dibuat (saya menggunakan algoritma integer ascending sederhana)

Untuk 1 juta file, metode cepat rm filename adalah 60 kali lebih cepat daripada metode lambat ... sekali lagi, saya tidak tahu apakah ini masalah "pengurutan", atau masalah tabel hash di belakang layar ... Saya menduga itu bukan masalah sederhana menyortir, karena mengapa ls -1 -fsengaja memberi saya unsort daftar dari baru ditambahkan "diurutkan" urutan nama file ...

Saya hanya ingin tahu apa yang sedang terjadi di sini, jadi saya tidak perlu berhari-hari (ya berhari-hari) untuk menghapus 10 juta file berikutnya :) .... Saya mengatakan "hari" karena saya mencoba banyak alternatif, dan kali yang terlibat meningkat secara tidak proporsional ke jumlah file yang terlibat .. jadi saya hanya menguji 1 juta secara detail

BTW: Menghapus file melalui "daftar daftar" nama sebenarnya lebih cepat daripada rm -rfdengan faktor 2.
dan: rm -r30 kali lebih lambat dari metode "daftar disortir"

... tetapi apakah "beres" masalah di sini? atau itu lebih terkait dengan metode penyimpanan hashing (atau apa pun) yang digunakan oleh ext4?

Hal yang cukup membingungkan saya adalah bahwa setiap panggilan rm filenametidak terkait dengan yang sebelumnya .. (yah, setidaknya itu seperti itu dari perspektif 'bash')

Saya menggunakan drive Ubuntu / bash / 'ext4' / SATA II.

Peter.O
sumber
1
Kamu melakukannya dengan salah! (tm) Pernah dengar find -delete?
alex
2 tes Anda mulai dalam kondisi yang tidak sama (Saya tidak menganggap ini memang penting): satu membaca nama file dari file, dan yang lain membaca nama file dari file yang telah dibuat (diurutkan) segera sebelum tes. Mungkin saja file yang sedang di-cache dalam case ke-2 memainkan beberapa (atau mungkin tidak, siapa yang tahu). Agar tes berada dalam kondisi yang lebih setara, mungkin Anda harus melakukan yang sederhana catke file baru sebelum tes 1 - menggantikan sorttes 2.
imz - Ivan Zakharyaschev
Dan saya sarankan Anda untuk menyajikan pengamatan Anda dan pertanyaan Anda dengan cara yang lebih jelas. Tolong, satu per satu: bandingkan hanya 2 kasus dalam satu pertanyaan, bawa dua kasus penting ke permukaan, semua yang lain hanya informasi latar belakang; tolong jelaskan ini. Tolong, jangan mencampur beberapa pengamatan dalam satu posting.
imz - Ivan Zakharyaschev
Menampilkan waktu sistem dan ruang pengguna dari Anda mungkin juga penting untuk menyelesaikan teka-teki, jadi harap sertakan mereka dalam pertanyaan Anda. Manakah dari mereka yang membuat perbedaan besar dalam tes Anda?
imz - Ivan Zakharyaschev
1
Optimalisasi prematur adalah akar dari semua kejahatan. :) Kapan Anda pernah menghapus 10 Juta file? 100.000 per detik tampaknya cukup cepat bagi saya (untuk merusak sistem Anda).
pengguna tidak dikenal

Jawaban:

2

rm -r diharapkan lambat karena bersifat rekursif. Traversal pertama yang mendalam harus dibuat pada struktur direktori.

Sekarang bagaimana Anda membuat 10 juta file? Apakah Anda menggunakan beberapa skrip yang loop pada beberapa pesanan? 1.txt, 2.txt, 3.txt ... jika ya maka file-file itu juga dapat dialokasikan pada urutan yang sama dalam blok yang sesuai di hdd.so menghapus pada urutan yang sama akan lebih cepat.

"ls -f" akan mengaktifkan -aU yang berisi daftar dalam urutan direktori yang lagi-lagi bersifat rekursif.

rajaganesh87
sumber
1
McAlot: Saya tidak bisa melihat bagaimana 'rekursif' akan penting dalam kasus ini , karena tidak ada sub-direktori yang terlibat ... Ya saya memang menggunakan "1.txt, 2.txt, 3.txt '. Mungkin ada beberapa hal-hal yang saling berinteraksi: misalnya, Mengapa hanya perlu 1 menit 30-an untuk membuat 1 juta file, tetapi butuh 7 juta 10 untuk membuat 2 juta, dan setelah menghapusnya, menciptakan kembali 1 juta lebih banyak membutuhkan waktu lebih lama (9 m 30-an) yang aneh; semuanya berjalan perlahan-lahan tiba-tiba. Ini telah terjadi sebelumnya juga. Saya pikir (?) menghapus direktori memperbaikinya. Apakah ada daemon file yang terlibat (nautilus; cari) mungkin? Akan dilanjutkan ...
Peter.O
Secara umum, sistem file tidak dioptimalkan untuk berurusan dengan sejumlah besar file di direktori yang sama. Saya tidak terbiasa dengan ext4 secara khusus, tetapi untuk format lain entri direktori hanya ditandai sebagai tidak digunakan ketika file dihapus. Itu berarti mereka masih harus dilewati ketika melakukan operasi di direktori. Itu akan menjelaskan perilaku yang Anda lihat.
KeithB
1
Saya menghapus direktori 'sekarang lebih lambat', dan menggunakan nama yang berbeda untuk direktori baru. Waktu untuk membuat 1 juta file sekarang kembali ke 1m 33s (vs 9m 30s ketika direktori "berisi" 2 juta file yang dihapus, juta pertama memiliki nama yang sama dengan 1 juta yang baru ditambahkan) ... menarik, dan itu hitung dengan komentar "... hanya ditandai sebagai tidak terpakai" ... sampai di sana; itu mulai masuk akal :)
Peter.O
@ fred.bear Buruk saya, saya benar-benar tidak tahu hierarki yang sebenarnya dan jawaban saya adalah tebakan. juga tes Anda sebenarnya menekankan metadata tetapi bukan file yang sebenarnya karena mereka adalah file kosong. Cara terbaik untuk membandingkan masalah seperti ini adalah dengan mengambil file dari / var atau cache server web. Lagi pula tes Anda juga terdengar menarik, dapatkah Anda mencoba menghapus dengan dua metode yang tercantum dalam direktori yang berbeda .. katakanlah seperti /sample1/1.txt ,2.txt ... dan /sample2/1.txt ,2.txt ..
rajaganesh87
@ Mr.Confused.A.Lot ... Terima kasih atas bantuan Anda. Penjelasan Anda membantu saya memahami lebih lanjut tentang sistem file dan beberapa perilakunya ... Saya sekarang memiliki pengertian yang masuk akal tentang apa yang menyebabkan masalah kecepatan berbeda ... beberapa hanya pilihan perintah bash, dan yang lain hanyalah masalah sistem file ( Saya dibiarkan dengan moto baru: "besar itu buruk" untuk direktori ... (untuk beberapa tindakan, setidaknya) ...
Peter.O
2

Anda harus mengoptimalkan struktur file. Jadi, bukannya

for i in $(seq 1 1000); do touch file.$i; done

lakukan sesuatu yang lebih pintar seperti (diasumsikan bash):

function bucklocate() 
{ 
    hash=$(echo -n "$1"|md5sum|cut -f1); 
    echo -n "${hash:1:1}/${hash:7:1}/${hash:9:2}/$1"; 
}

hexdig="{0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f}"
eval mkdir -p $hexdig/$hexdig/$hexdig$hexdig


for i in $(seq 1 1000); do touch $(bucklocate file.$i); done

Sekarang contoh ini agak lambat karena penggunaan md5sum [1], gunakan sesuatu seperti yang berikut ini untuk respons yang jauh lebih cepat, selama Anda tidak memerlukan nama file tertentu, duplikat tidak menjadi masalah dan tidak perlu untuk hash berulang dari nama tertentu :)

mkdir -pv {0,1,2,3,4,5,6}/{0,1,2,3,4,5,6,7,8,9,10,12}
for  a in $(seq 1 100); do i=$RANDOM; echo touch "$(($i%7))/$(($i%13))/file.$i"; done

Tentu saja ini semua konsep pinjaman sembarangan dari hashtables

lihat
sumber
Saya pikir Anda mengatakan "gunakan direktori yang lebih kecil" ... Itu ide yang menarik; sebuah DBMS rumahan yang menghasilkan pohon dari sekelompok file 'tanpa pohon' ". Beberapa orang mungkin menyebutnya perencanaan kedepan :) ... Jika berhasil (dan mungkin memang demikian), maka itu adalah ide yang bagus ! :) ... Saya mulai mendapatkan gagasan bahwa 'besar itu buruk' ketika datang ke jumlah file dalam direktori (setidaknya untuk ext4) ... Anda telah mempresentasikan solusi pemecahan masalah awal (+1) dan saya ' Saya perlahan-lahan mendapatkan ide mengapa beberapa metode penghapusan lebih cepat daripada yang lain dalam direktori tertentu; kecil atau besar ... Terima kasih
Peter.O
Yup maaf karena tidak lebih eksplisit pada gagasan menjaga dirs kecil
sehe