Hapus 10 juta file + dari ZFS, secara efektif

30

Saya telah menulis program kereta yang secara tidak sengaja membuat sekitar 30 juta file di bawah / tmp. (Bug diperkenalkan beberapa minggu yang lalu, dan itu membuat beberapa subdirektori per detik.) Saya bisa mengganti nama / tmp ke / tmp2, dan sekarang saya harus menghapus file. Sistemnya adalah FreeBSD 10, sistem file root adalah zfs.

Sementara itu salah satu drive di cermin salah, dan saya telah menggantinya. Drive ini memiliki dua disk SSD 120GB.

Inilah pertanyaannya: mengganti hard drive dan memasang kembali seluruh array membutuhkan waktu kurang dari satu jam. Menghapus file / tmp2 adalah cerita lain. Saya telah menulis program lain untuk menghapus file, dan hanya dapat menghapus 30-70 subdirektori per detik. Diperlukan 2-4 hari untuk menghapus semua file.

Bagaimana mungkin resilver seluruh array membutuhkan waktu satu jam, tetapi menghapus dari disk membutuhkan waktu 4 hari? Mengapa kinerja saya sangat buruk? 70 penghapusan / detik nampaknya performanya sangat sangat buruk.

Saya bisa menghapus inode untuk / tmp2 secara manual, tetapi itu tidak akan membebaskan ruang, kan?

Mungkinkah ini masalah dengan zfs, atau hard drive atau apa?

Nagylz
sumber
1
Saya bukan ahli zfs, jadi saya tidak dapat berbicara dengan penyempurnaan kinerja Anda atau apa yang mungkin Anda lakukan untuk memperbaikinya (itu juga akan mengambil banyak informasi dan mungkin sebaiknya dilakukan langsung oleh seorang ahli). Namun, saya dapat mengatakan bahwa resilver terjadi pada level blok, sementara penghapusan Anda terjadi pada level sistem file. Filesystem sebagian besar akan overhead ketika menghapus buffer inode bagillion seperti itu.
Spooler
Silakan posting Anda df -hdan zpool listdan zfs list.
ewwhite
5
Menulis program lain: rm -rf /tmp2tidak akan melakukan pekerjaan?
Thorbjørn Ravn Andersen
2
Bisakah Anda tidak hanya reboot? /tmpharus menjadi tmpfssistem file dan disimpan dalam memori.
Blender

Jawaban:

31

Menghapus ZFS itu mahal. Terlebih lagi jika Anda mengaktifkan deduplikasi pada sistem file (karena file deduped dereferencing mahal). Snapshots juga dapat memperumit masalah.

Anda mungkin lebih baik menghapus /tmpdirektori daripada data yang terkandung di dalamnya.

Jika /tmpmerupakan sistem file ZFS, hapus dan buat kembali.

putih
sumber
1
@ nagylzs Dalam hal ini saya akan menyarankan menjadikannya sistem file ZFS yang terpisah. Kemudian Anda dapat memindahkan / tmp saat ini keluar dari jalan, memindahkan / tmp baru ke tempatnya, dan menghapus file pada waktu luang sistem. Hasil: downtime minimal plus sedikit penurunan kinerja (dapat dimitigasi ionice, dengan anggapan FreeBSD memilikinya) ketika penghapusan sedang berjalan.
CVn
9
Saya salah. Itu adalah sistem file yang terpisah. Inilah yang berhasil: reboot ke mode pengguna tunggal, lalu lakukan "zfs delete zroot / tmp; zfs create zroot / tmp; chmod 41777 / tmp"
nagylzs
6
Itu total downtime 5 menit. Fantastis! :-)
nagylzs
1
Nah, itu juga berbicara tentang kekhawatiran saya, bahwa penghapusan fike tidak pernah membebaskan ruang karena foto-foto. Tapi tmp akan diatur untuk tidak membuat snapshot berkala otomatis, kan ?
JDługosz
1
Sebenarnya ini adalah: zfs create -o compression = on -o exec = on -o setuid = off zroot / tmp; chmod 1777 / zroot / tmp; zfs mengatur mountpoint = / tmp zroot / tmp; Saya tidak yakin cara mematikan snapshot otomatis. Ada "zfs set com.sun: auto-snapshot = false" tetapi hanya berfungsi pada solaris, saya pikir.
nagylzs
27

Bagaimana mungkin resilver seluruh array membutuhkan waktu satu jam, tetapi menghapus dari disk membutuhkan waktu 4 hari?

Pertimbangkan sebuah gedung kantor.

Menghapus semua komputer dan furnitur dan barang-barang dari semua kantor di semua lantai membutuhkan waktu lama , tetapi meninggalkan kantor segera dapat digunakan oleh klien lain.

Menghancurkan seluruh bangunan dengan RDX adalah seluruh banyak lebih cepat, tetapi klien berikutnya adalah cukup mungkin untuk mengeluh tentang bagaimana berangin tempat ini.

Phill W.
sumber
5
ZFS bukan gedung kantor :)
developerbmw
9
@developerbmw sebenarnya juga tidak ada file atau folder di sana, tetapi kita perlu konsep metaforis untuk memahami apa yang sedang terjadi.
JamesRyan
2
@ JamesRyan ya itu sebenarnya analogi yang bagus ... Saya hanya menjadi bodoh
developerbmw
5

Ada beberapa hal yang terjadi di sini.

Pertama, semua teknologi disk modern dioptimalkan untuk transfer massal. Jika Anda perlu memindahkan 100MB data, mereka akan melakukannya lebih cepat jika mereka berada di satu blok yang berdekatan daripada tersebar di semua tempat. SSD sangat membantu di sini, tetapi bahkan mereka lebih suka data dalam blok yang berdekatan.

Kedua, resilver cukup optimal sejauh operasi disk berjalan. Anda membaca sepotong besar data yang berdekatan dari satu disk, melakukan beberapa operasi CPU cepat di atasnya, kemudian menulis ulang di sepotong besar yang berdekatan ke disk lain. Jika listrik gagal setengah jalan, bukan masalah besar - Anda hanya akan mengabaikan data dengan checksum yang buruk dan melanjutkan seperti biasa.

Ketiga, menghapus file sangat lambat . ZFS sangat buruk, tetapi secara praktis semua sistem file lambat untuk dihapus. Mereka harus memodifikasi sejumlah besar potongan data yang berbeda pada disk dan mengatur waktu dengan benar (yaitu menunggu) sehingga sistem file tidak rusak jika daya gagal.

Bagaimana mungkin resilver seluruh array membutuhkan waktu satu jam, tetapi menghapus dari disk membutuhkan waktu 4 hari?

Resilver adalah sesuatu yang membuat disk sangat cepat, dan penghapusan adalah sesuatu yang lambat pada disk. Per megabyte disk, Anda hanya perlu melakukan sedikit resilver. Anda mungkin memiliki seribu file di ruang itu yang perlu dihapus.

70 penghapusan / detik nampaknya performanya sangat sangat buruk

Tergantung. Saya tidak akan terkejut dengan ini. Anda belum menyebutkan jenis SSD apa yang Anda gunakan. Intel modern dan SSD Samsung cukup bagus dalam operasi semacam ini (baca-modifikasi-tulis) dan akan berkinerja lebih baik. SSD yang lebih murah / lebih lama (mis. Corsair) akan lambat. Jumlah operasi I / O per detik (IOPS) adalah faktor penentu di sini.

ZFS adalah sangat lambat untuk menghapus hal-hal. Biasanya, itu akan melakukan penghapusan di latar belakang sehingga Anda tidak melihat penundaan. Jika Anda melakukan sejumlah besar dari mereka itu tidak dapat menyembunyikannya dan harus menunda Anda.


Lampiran: mengapa penghapusan lambat?

  • Menghapus file memerlukan beberapa langkah. Metadata file harus ditandai sebagai 'dihapus', dan akhirnya harus direklamasi sehingga ruang dapat digunakan kembali. ZFS adalah 'filesystem terstruktur log' yang berkinerja terbaik jika Anda hanya pernah membuat sesuatu, tidak pernah menghapusnya. Struktur log berarti bahwa jika Anda menghapus sesuatu, ada celah di log dan data lain harus disusun ulang (didefragmentasi) untuk mengisi kesenjangan. Ini tidak terlihat oleh pengguna tetapi umumnya lambat.
  • Perubahan harus dibuat sedemikian rupa sehingga jika daya gagal sebagian, sistem file tetap konsisten. Seringkali, ini berarti menunggu hingga disk mengonfirmasi bahwa data benar-benar ada di media; untuk SSD, itu bisa memakan waktu lama (ratusan milidetik). Efek bersih dari ini adalah bahwa ada lebih banyak pembukuan (yaitu operasi disk I / O).
  • Semua perubahan itu kecil. Alih-alih membaca, menulis, dan menghapus seluruh blok flash (atau silinder untuk disk magnetik), Anda perlu memodifikasi sedikit. Untuk melakukan ini, perangkat keras harus membaca di seluruh blok atau silinder, memodifikasinya dalam memori, kemudian menuliskannya ke media lagi. Ini butuh waktu lama.
Ian Howson
sumber
Saya tidak tahu tentang ZFS, tetapi beberapa sistem file memungkinkan Anda memutus tautan direktori dengan konten, tetapi kontennya baru dihapus nanti saat fase pengumpulan / defrag / pembersihan sampah. Apakah ZFS memiliki utilitas untuk melakukan penghapusan malas seperti itu mungkin? Ini tidak akan benar-benar mempercepat penghapusan OP tetapi akan membuatnya kurang bermasalah jika itu terjadi secara implisit selama housekeeping.
Vality
2

Bagaimana mungkin resilver seluruh array membutuhkan waktu satu jam, tetapi menghapus dari disk membutuhkan waktu 4 hari?

Ini dimungkinkan karena dua operasi bekerja pada lapisan yang berbeda dari tumpukan sistem file. Resilver dapat menjalankan level rendah dan sebenarnya tidak perlu melihat file individual, menyalin sebagian besar data sekaligus.

Mengapa kinerja saya sangat buruk? 70 penghapusan / detik nampaknya performanya sangat sangat buruk.

Itu memang harus melakukan banyak pembukuan ...

Saya bisa menghapus inode untuk / tmp2 secara manual, tetapi itu tidak akan membebaskan ruang, kan?

Saya tidak tahu untuk ZFS, tetapi jika bisa secara otomatis pulih dari itu, kemungkinan besar, pada akhirnya, melakukan operasi yang sama yang sudah Anda lakukan, di latar belakang.

Mungkinkah ini masalah dengan zfs, atau hard drive atau apa?

Apakah zfs scrubmengatakan sesuatu?

AnoE
sumber
2

Menghapus banyak file tidak pernah benar-benar operasi yang cepat.

Untuk menghapus file pada sistem file apa pun , Anda perlu membaca indeks file, menghapus (atau menandai sebagai dihapus) entri file dalam indeks, menghapus metadata lain yang terkait dengan file, dan menandai ruang yang dialokasikan untuk file tersebut sebagai tidak digunakan. Ini harus dilakukan secara terpisah untuk setiap file yang akan dihapus, yang berarti menghapus banyak file memerlukan banyak I / Os kecil. Untuk melakukan ini dengan cara yang memastikan integritas data jika terjadi kegagalan daya, menambah biaya tambahan.

Bahkan tanpa kekhasan yang diperkenalkan ZFS, menghapus 30 juta file biasanya berarti lebih dari seratus juta operasi I / O yang terpisah. Ini akan memakan waktu lama bahkan dengan SSD yang cepat. Seperti yang telah disebutkan orang lain, desain ZFS semakin menambah masalah ini.

bwDraco
sumber
2

Ian Howson memberikan jawaban yang bagus mengapa lambat.

Jika Anda menghapus file secara paralel, Anda mungkin melihat peningkatan kecepatan karena penghapusan dapat menggunakan blok yang sama dan dengan demikian dapat menyimpan penulisan ulang blok yang sama berkali-kali.

Jadi cobalah:

find /tmp -print0 | parallel -j100 -0 -n100 rm

dan lihat apakah kinerjanya lebih baik daripada 70 penghapusan Anda per detik.

Ole Tange
sumber
0

Sangat sederhana jika Anda membalikkan pemikiran Anda.

  1. Dapatkan drive kedua (sepertinya Anda sudah memilikinya)

  2. Salin semuanya dari drive A ke drive B dengan rsync, tidak termasuk direktori / tmp. Rsync akan lebih lambat daripada salinan blok.

  3. Reboot, menggunakan drive B sebagai volume boot baru

  4. Memformat ulang drive A.

Ini juga akan mendefrag drive Anda dan memberi Anda direktori baru (baik, defrag tidak begitu penting dengan SSD tetapi membuat linierisasi file Anda tidak akan menyakiti apa pun)

Peter
sumber
Pertama-tama salin semuanya kecuali / tmp? Jadi termasuk / dev dan / proc? Kedua, terdengar agak kludgy bagi saya, terutama pada server produksi.
Hennes
Saya berasumsi dia cukup pintar untuk mengecualikan non-file, volume yang dipasang, dan folder virtual-memory, yang sebagian besar tidak dapat ditebak di sini. Atau lakukan dari boot pemeliharaan di mana tidak ada yang penting.
peter
Saya pikir Anda juga bisa zfs send/recv(menyalin tingkat blok) semua sistem file lain kecuali sistem file root (di mana / tmp terletak dalam kasus ini) dan menyalin data yang tersisa pada sistem file root secara manual (tidak termasuk / tmp tentu saja).
user121391
2
Itu akan kehilangan snapshot dan memotong beberapa fitur keandalan. Merindukan titik menggunakan zfs.
JDługosz
2
@ JDługosz poin yang valid, tetapi hanya relevan jika pengguna peduli. Seperti "backup saya rusak, bagaimana cara memperbaikinya?" -> "Apakah Anda memerlukan file cadangan?" -> "Tidak." -> "Reformat".
peter
-1

Anda memiliki 30 juta entri dalam daftar yang tidak disortir. Anda memindai daftar untuk entri yang ingin Anda hapus dan Anda menghapusnya. Sekarang Anda hanya memiliki 29.999.999 entri dalam daftar Anda yang tidak disortir. Jika semuanya ada di / tmp, mengapa tidak reboot saja?


Diedit untuk mencerminkan informasi dalam komentar: Pernyataan masalah: Menghapus sebagian besar, tetapi tidak semua , dari 30M + file yang dibuat secara salah di / tmp membutuhkan waktu lama.
Masalah 1) Cara terbaik untuk menghapus banyak file yang tidak diinginkan dari / tmp.
Masalah 2) Memahami mengapa sangat lambat untuk menghapus file.

Solusi 1) - / tmp diatur ulang ke kosong saat boot oleh sebagian besar * distribusi nix. Namun FreeBSD, bukan salah satunya.
Langkah 1 - menyalin file menarik di tempat lain.
Langkah 2 - Sebagai root

 $ grep -i tmp /etc/rc.conf  
 clear_tmp_enable="YES" # Clear /tmp at startup.  

Langkah 3 - reboot.
Langkah 4 - ubah clear_tmp_enable kembali ke "Tidak".
File yang tidak diinginkan sekarang hilang karena ZFS di FreeBSD memiliki fitur bahwa "Menghancurkan sebuah dataset jauh lebih cepat daripada menghapus semua file yang berada pada dataset, karena tidak melibatkan pemindaian semua file dan memperbarui semua metadata yang sesuai. " jadi yang harus dilakukan saat boot adalah mengatur ulang metadata untuk dataset / tmp. Ini sangat cepat.

Solusi 2) Mengapa sangat lambat? ZFS adalah sistem file luar biasa yang mencakup fitur seperti akses direktori waktu konstan. Ini bekerja dengan baik jika Anda tahu apa yang Anda lakukan, tetapi bukti menunjukkan bahwa OP bukan ahli ZFS. OP belum mengindikasikan bagaimana mereka mencoba untuk menghapus file, tetapi pada tebakan, saya akan mengatakan mereka menggunakan variasi pada "find regex -exec rm {} \;". Ini bekerja dengan baik dengan angka kecil tetapi tidak skala karena ada tiga operasi serial terjadi 1) dapatkan daftar file yang tersedia (mengembalikan 30 juta file dalam urutan hash), 2) menggunakan regex untuk memilih file berikutnya yang akan dihapus, 3 ) beri tahu OS untuk menemukan dan menghapus file itu dari daftar 30 juta. Bahkan jika ZFS mengembalikan daftar dari memori dan jika cache 'find', regex masih harus mengidentifikasi file berikutnya yang akan diproses dari daftar dan kemudian memberitahu OS untuk memperbarui metadata untuk mencerminkan perubahan itu dan kemudian memperbarui daftar sehingga tidak diproses lagi.

Paul Smith
sumber
1
Saya pikir Anda salah paham pertanyaannya. Saya perlu menghapus sebagian besar file. Yaitu, 30 juta file.
nagylzs
@nagylzs / tmp dihapus saat reboot. Jika Anda ingin menghapus sebagian besar , maka Anda hanya ingin menyimpan beberapa , yaitu kurang dari setengah, jadi salin yang Anda ingin simpan dan kemudian reboot untuk menyingkirkan sisanya. Alasan penghapusan Anda sangat lambat adalah karena memiliki banyak file dalam direktori menghasilkan daftar besar yang tidak disortir yang perlu diproses untuk menemukan file yang akan dioperasikan, yang membutuhkan waktu. Satu-satunya masalah di sini adalah PEBCAK.
Paul Smith
Direktori ZFS tidak disortir ? Saya pikir zfs secara khusus menangani direktori besar dengan baik.
JDługosz
Yah, / tmp tidak dihapus, hanya file terkait X. Setidaknya di FreeBSD. Lagipula itu tidak dapat dihapus saat boot, karena itu akan memakan waktu berhari-hari untuk menghapus skrip rc secara normal.
nagylzs
@JDlugosz - ZFS jauh lebih baik daripada kebanyakan, tetapi daftar inode (yang semua direktori) tidak disortir.
Paul Smith