Kekerapan ZFS scrub untuk VPS pool satu cakera
ZFS scrub membaca blok untuk mengesan kerosakan data. Pada VPS satu cakera, ia tidak boleh membaiki ralat. Ketahui jadual scrub yang sesuai agar prestasi VPS tidak terjejas.
Apakah fungsi sebenar ZFS scrub
ZFS scrub membaca setiap blok yang diperuntukkan dalam pool, mengira semula checksum-nya, dan membandingkan hasil tersebut dengan checksum yang disimpan dalam penunjuk blok induk (parent block pointer). Jika kedua-duanya tidak sepadan, ZFS akan membaiki blok tersebut menggunakan redundansi yang ada dalam pool. Tiada fungsi lain dalam ZFS yang melakukan tugas ini. Bacaan biasa hanya mengesahkan blok yang anda akses, jadi fail yang tidak dibuka selama dua tahun akan kekal tidak disahkan sehingga scrub membacanya.
Scrub bukanlah fsck, iaitu proses pembaikan luar talian yang diperlukan oleh sistem fail lain. Tiada fasa pembaikan struktur kerana ZFS tidak pernah membiarkan format pada cakera dalam keadaan rosak: setiap penulisan pergi ke lokasi baharu dan uberblock, iaitu penunjuk akar pool, dikemas kini pada peringkat terakhir. Scrub juga tidak membaca keseluruhan peranti. Ia hanya membaca blok yang diperuntukkan, itulah sebabnya pool yang hampir kosong boleh selesai di-scrub dalam beberapa minit, manakala pool yang sama pada tahap 80% penuh mengambil masa yang jauh lebih lama.
Scrub berjalan pada keutamaan I/O paling rendah yang dimiliki oleh ZFS. Pada Linux, zfs_vdev_scrub_max_active ditetapkan secara lalai kepada 2, jadi paling banyak dua bacaan scrub dilakukan serentak bagi setiap vdev (peranti maya, iaitu kumpulan cakera yang dianggap ZFS sebagai satu unit). zfs_scrub_min_time_ms ditetapkan secara lalai kepada 750, iaitu masa minimum yang dihabiskan oleh thread penyelarasan (sync thread) untuk kerja scrub di antara proses flushes kumpulan transaksi, iaitu komit berkala yang menggabungkan penulisan ZFS. Pada mesin yang melahu, scrub akan menggunakan keseluruhan cakera. Apabila terdapat beban kerja, ia akan mengurangkan penggunaan. Pada pool dengan satu atau dua peranti, tiada ruang untuk ia mengurangkan beban, itulah sebabnya penjadualan lebih penting di sini berbanding pada kerangka besar dengan enam puluh pemacu.
Mengapa melakukan scrub pada pool yang tidak boleh membaiki dirinya sendiri?
Ini adalah ayat yang menentukan segala-galanya pada pool bersaiz kecil. Tanpa redundansi, scrub mengesan kerosakan tetapi tidak dapat membaikinya. Satu cakera maya (virtual disk) dalam VPS adalah pool tanpa mirror dan tanpa parity. ZFS akan membaca blok yang rosak, gagal dalam checksum, mengiranya dalam lajur CKSUM, menamakan fail tersebut, dan berhenti di situ, kerana tiada salinan kedua untuk proses bina semula.
Dua pengecualian separa perlu diketahui. ZFS menyimpan salinan tambahan metadata secara lalai (redundant_metadata=all), yang ditulis ke kawasan berbeza pada peranti, jadi scrub boleh membaiki entri direktori atau penunjuk blok yang rosak walaupun pada pool satu peranti. Dan dataset dengan copies=2 menyimpan dua salinan blok datanya, dengan kos ruang dua kali ganda. Tiada satu pun yang terselamat jika peranti tersebut hilang. Dokumentasi sifat copies memberi amaran tentang perkara ini: jangan bina pool berjalur (striped pool), tetapkan copies=2, dan percaya anda mempunyai redundansi.
Jadi, pada pool satu peranti, scrub memberikan anda satu perkara: pemberitahuan awal dan tepat. Ia menukarkan kerosakan senyap kepada nama fail dalam zpool status -v sementara sandaran (backup) anda masih menyimpan versi fail yang baik. Itu adalah hujah untuk sandaran, bukan hujah untuk menentang scrub. Jika anda belum menyelesaikan perbezaan antara imej point-in-time dan salinan sebenar di luar pelayan, mulakan dengan mengapa snapshot VPS bukan sandaran, kerana hasil scrub hanya membantu jika ada sesuatu yang lain menyimpan salinan yang utuh.
Scrub yang tidak menemui apa-apa juga merupakan satu hasil. Ia memberitahu anda bahawa data yang bakal anda percayai adalah utuh, iaitu perkara yang anda perlu tahu sebelum melakukan pemulihan (restore) atau migrasi.
Kerap manakah anda perlu melakukan scrub pada kumpulan VPS kecil?
Bulanan adalah tetapan lalai yang tepat, dan itulah yang diandaikan oleh pakej sedia ada. Debian dan Ubuntu membekalkan cron job yang melakukan scrub pada kumpulan yang sihat pada hari Ahad kedua setiap bulan. Sistem berkala FreeBSD berfungsi berdasarkan ambang dalam hari, dan daily_scrub_zfs_default_threshold menetapkan lalai kepada 35, yang diterangkan dalam manual sebagai lima minggu.
Melakukan scrub mingguan pada kumpulan kecil yang sibuk biasanya menelan kos yang lebih tinggi daripada manfaatnya. Dengan satu atau dua peranti, proses scrub bersaing untuk baris gilir yang sama dengan aplikasi anda, dan tiada peranti ganti untuk menampungnya. Pada VPS, peruntukan I/O adalah terhad, jadi bacaan yang digunakan oleh scrub adalah bacaan yang tidak diperoleh oleh pangkalan data anda. Berbanding dengan kos tersebut, scrub mingguan memberikan anda amaran paling awal tiga minggu lebih cepat tentang kerosakan yang anda tidak boleh baiki pun. Pertukaran itu hanya masuk akal apabila scrub tersebut murah.
Ukur masanya, kemudian buat keputusan. Jalankan satu scrub secara manual dan perhatikan berapa lama masa yang diambil.
- Jalankan
sudo zpool scrub tankpada waktu malam yang tenang dan rekodkan jumlah masa daripadazpool status. - Jika ia selesai dalam masa kurang daripada sejam dan pelayan tidak sibuk sepanjang malam, mingguan adalah pilihan yang berpatutan.
- Jika ia berjalan selama beberapa jam semasa kumpulan sedang melayan trafik, kekalkan kepada bulanan dan biarkan tugasan pakej yang menguruskannya.
- Ukur semula masanya apabila kumpulan berkembang dengan ketara, kerana tempoh scrub mengikut data yang diperuntukkan, bukan kapasiti cakera.
Apa sahaja yang anda pilih, catatkan di sebelah kerja pelayan berkala anda yang lain. Scrub tergolong dalam senarai yang sama dengan naik taraf pakej dan penggiliran log: lihat senarai semak penyelenggaraan pelayan Linux bulanan.
Memulakan, menjeda dan menghentikan scrub
sudo zpool scrub tank
sudo zpool status tankMenjeda dan menghentikan adalah operasi yang berbeza, dan memilih operasi yang salah boleh menyebabkan anda membuang masa berjam-jam untuk melakukan kerja berulang.
sudo zpool scrub -p tank
sudo zpool scrub tank
sudo zpool scrub -s tank-p melakukan jeda. Status dan kemajuan jeda diselaraskan ke cakera secara berkala, jadi scrub yang dijeda akan kekal walaupun selepas eksport atau but semula: pool akan kembali dengan status scrub yang masih dijeda, menunggu tindakan anda. Menjalankan zpool scrub sekali lagi akan menyambung semula daripada titik semak (checkpoint) terakhir yang ditulis ke cakera. -s pula menghentikan scrub, dan scrub seterusnya yang anda mulakan akan bermula dari awal. Gunakan -p apabila anda memerlukan cakera tersebut untuk kegunaan lain selama sejam. Gunakan -s apabila anda mahu scrub tersebut dibatalkan sepenuhnya.
Dua lagi flag yang perlu diketahui. -w menunggu sehingga scrub selesai sebelum kembali ke prompt, iaitu tindakan yang anda perlukan di dalam skrip supaya langkah seterusnya tidak bermula terlalu awal. -e hanya melakukan scrub pada fail yang mempunyai ralat data yang diketahui seperti yang dilaporkan oleh zpool status -v, iaitu cara pantas untuk mengesahkan bahawa fail yang anda pulihkan daripada sandaran kini sudah bersih.
ZFS menjalankan satu scrub atau resilver (proses bina semula yang berlaku selepas menggantikan peranti) pada satu masa bagi setiap pool, kerana kedua-duanya menggunakan I/O secara intensif. Jika peranti sedang dalam proses resilvering, scrub anda akan menunggu gilirannya.
Cara membaca status zpool semasa scrub berjalan
Jalankan sudo zpool status tank dan baca angka anda sendiri dan bukannya membandingkannya dengan angka orang lain. Semasa scrub, baris scan: memaparkan angka yang diimbas (scanned), angka yang dikeluarkan (issued), jumlah keseluruhan, angka yang dibaiki (repaired), peratusan siap, dan anggaran masa yang tinggal.
Scanned ialah fasa metadata: ZFS menelusuri pepohon blok dan mengumpul alamat yang perlu dibaca. Issued ialah fasa data: bacaan yang sebenarnya dihantar ke peranti, disusun mengikut urutan cakera. Scrub yang disusun adalah sebab mengapa terdapat dua pembilang, dan issued adalah pembilang yang menjejaki kemajuan sebenar. Pada peringkat awal, scanned berjalan jauh mendahului issued dan anggaran masa tidak membawa banyak makna. Nilai kemajuannya selepas sepuluh peratus pertama.
Repaired mengira bait yang ditulis semula daripada salinan yang baik. Pada pool tanpa redundansi, angka ini kekal sifar tidak kira apa yang ditemui oleh scrub, yang merupakan perkara sama seperti dinyatakan sebelum ini tetapi dalam bentuk angka yang boleh anda perhatikan.
Seterusnya, baca lajur bagi setiap peranti. READ dan WRITE mengira ralat I/O yang dilaporkan oleh peranti itu sendiri. CKSUM mengira blok yang gagal dalam pengesahan checksum, dan CKSUM ialah lajur yang menjadi tujuan utama scrub dijalankan. Nilai CKSUM bukan sifar pada peranti yang kelihatan sihat adalah benar: data telah kembali, tetapi data tersebut salah.
Baris terakhir ialah keputusan. errors: No known data errors bermaksud lulus. Sebarang status lain bermakna anda perlu menjalankan sudo zpool status -v tank, yang akan mencetak senarai lengkap ralat data sejak scrub lengkap yang terakhir, termasuk nama fail yang terjejas. Pulihkan fail tersebut daripada sandaran, jalankan sudo zpool clear tank untuk menetapkan semula pembilang, kemudian jalankan scrub sekali lagi. Setiap scrub yang lengkap akan membina semula senarai tersebut, jadi nama fail yang tiada selepas scrub bersih sepenuhnya bermakna fail tersebut benar-benar telah hilang.
Tugasan scrub berkala yang manakah ada pada sistem anda?
Jangan andaikan bahawa ia wujud, dan jangan andaikan hanya ada satu. Mekanismenya berbeza mengikut platform dan pakej. Format pool adalah sama di mana-mana, yang menjadikannya mudah untuk terlupa bahawa alatan di sekelilingnya tidak sama, dan cara ZFS dibekalkan pada FreeBSD berbanding Linux adalah perbezaan yang penting di sini.
Pada FreeBSD, tugasan ini berada dalam sistem periodic. Tetapkan perkara ini dalam /etc/periodic.conf:
daily_scrub_zfs_enable="YES"
daily_scrub_zfs_pools="tank"
daily_scrub_zfs_default_threshold="35"daily_scrub_zfs_pools ialah senarai nama pool yang dipisahkan dengan ruang, dan membiarkannya kosong akan melakukan scrub pada setiap pool. daily_scrub_zfs_default_threshold ialah bilangan hari antara scrub apabila tiada ambang khusus pool ditetapkan, dan manual memberikan 35 sebagai nilai lalai. Tugasan harian berjalan setiap hari; ia hanya memulakan scrub sebaik sahaja ambang masa telah berlalu.
Pada Linux, ia bergantung pada pakej ZFS pengedaran anda, dan sesetengah sistem membawa kedua-dua mekanisme serentak. Terdapat pemasa systemd bagi setiap pool, zfs-scrub-monthly@tank.timer dan zfs-scrub-weekly@tank.timer, yang diaktifkan satu pool pada satu masa. Debian dan Ubuntu juga membekalkan /etc/cron.d/zfsutils-linux, yang menjalankan skrip untuk melakukan scrub pada setiap pool yang ONLINE pada hari Ahad kedua setiap bulan. Semak apa yang anda miliki sebelum menambah apa-apa:
systemctl list-timers 'zfs-*'
ls /etc/cron.d/ | grep -i zfs
sudo zpool history tank | grep scrubzpool history ialah jawapan yang tepat, kerana ia merekodkan scrub yang sebenarnya dimulakan oleh pool, berserta tarikh. Dua scrub sebulan bermakna kedua-dua mekanisme sedang aktif dan salah satu daripadanya perlu dibuang. Untuk mengaktifkan pemasa:
sudo systemctl enable --now zfs-scrub-monthly@tank.timerRuang bebas lebih penting daripada sebarang tetapan boleh ubah
Tempoh scrub pada pool yang kecil ditentukan oleh jumlah data yang diperuntukkan dan tahap penyebarannya. Memenuhi pool akan memburukkan kedua-dua faktor tersebut.
Panduan OpenZFS adalah untuk mengekalkan ruang bebas pool melebihi 10%. Di bawah paras itu, metaslab, iaitu ketulan data yang digunakan oleh pengumpuk (allocator), mula melintasi ambang 4% ruang bebas, dan pengumpuk akan bertukar daripada first-fit kepada best-fit. Best-fit jauh lebih intensif dari segi penggunaan CPU. Latensi tulis meningkat, fragmentasi berlaku, dan scrub seterusnya menjadi lebih perlahan kerana jumlah data yang sama kini tiba sebagai bacaan yang lebih banyak dan lebih kecil.
Oleh itu, tuil pertama bukanlah tetapan boleh ubah. Ia adalah memadamkan fail. Snapshot lama biasanya menjadi punca pada kotak ZFS, diikuti oleh imej dan lapisan Docker yang tidak dibersihkan serta pakej kernel yang tertinggal akibat naik taraf. Jalankan zfs list -o space sebelum anda menyentuh perkara lain, kerana ia memisahkan ruang yang dipegang oleh snapshot daripada ruang yang dipegang oleh data aktif.
Seterusnya, secara ringkas mengenai tombol tetapan. Pada Linux, anda boleh membaca nilai semasa:
cat /sys/module/zfs/parameters/zfs_scrub_min_time_ms
cat /sys/module/zfs/parameters/zfs_vdev_scrub_max_activeFreeBSD mendedahkan parameter yang sama melalui sysctl, jadi cari nilai anda dengan sysctl -a | grep scrub. Meningkatkan nilai tersebut akan menamatkan scrub dengan lebih cepat dan menjadikan aplikasi anda lebih perlahan. Menurunkan nilai tersebut memberikan kesan sebaliknya. Pada pool dengan satu atau dua peranti, tiada tetapan yang memberikan kedua-dua kelebihan, kerana hanya terdapat satu baris gilir untuk dibahagikan. Tombol tetapan jarang membaiki reka bentuk yang lemah. Jika scrub bulanan menjejaskan prestasi, kesimpulan yang jujur adalah pool tersebut terlalu penuh atau peranti terlalu perlahan, dan tetapan boleh ubah hanya memindahkan masalah tersebut.
Masa scrub ialah pratonton resilver anda
Proses resilver melakukan langkah yang sama seperti scrub: ia membaca blok yang diperuntukkan, mengesahkannya, dan menulis blok yang hilang ke peranti gantian. Oleh itu, masa yang diambil oleh scrub adalah pratonton paling tepat tentang tempoh masa yang diperlukan untuk pembinaan semula (rebuild), serta tempoh masa pool akan beroperasi dengan redundansi yang berkurangan sepanjang proses tersebut.
ZFS menjadualkan kerja resilver dengan lebih agresif berbanding kerja scrub, jadi proses pembinaan semula biasanya selesai lebih cepat daripada scrub bagi pool yang sama. Anggap masa scrub anda sebagai had atas yang konservatif. Jika scrub mengambil masa sembilan jam, rancang tetingkap pembinaan semula dalam tempoh tersebut, dan fahami bahawa kegagalan peranti kedua dalam tetingkap itu akan menyebabkan kehilangan pool. Itulah hujah praktikal untuk pasangan cermin (mirrored pairs) berbanding satu kumpulan raidz yang luas, memandangkan raidz, iaitu susun atur pariti yang digunakan oleh ZFS sebagai ganti RAID 5, membina semula dengan membaca setiap peranti yang masih berfungsi.
Pada pool peranti tunggal, tiada proses resilver langsung. Peranti tersebut rosak, dan pool tersebut turut hilang bersamanya. Masa pemulihan anda ialah masa pemulihan (restore) anda, jadi ukur proses restore tersebut sebaliknya. Proses restore yang tidak pernah anda jalankan bukanlah satu pelan pemulihan.
Apakah perubahan apabila anda menyewa cakera
Pada VPS, peranti blok adalah maya. Hipervisor mempersembahkan satu volum, dan di bawahnya mungkin terdapat NVMe tempatan, atau volum rangkaian bereplikasi yang mempunyai pariti tersendiri. Terdapat dua kesan terhadap proses scrub.
Pertama, redundansi platform tidak dapat dilihat oleh ZFS, dan ZFS tidak boleh menggunakannya. Jika platform membaiki ralat media di bawah anda, ZFS tidak akan melihat masalah tersebut. Jika platform memberikan blok yang salah, ZFS akan mengesannya tetapi tidak dapat membaikinya, kerana salinan yang betul berada di sebalik sempadan tersebut.
Kedua, anda biasanya tidak boleh membaca data SMART (self-monitoring, analysis and reporting technology) bagi peranti di bawah cakera maya, jadi amaran awal yang bergantung kepada pemantauan kesihatan cakera pada VPS mungkin tidak tersedia langsung. Pembilang CKSUM daripada proses scrub anda menjadi isyarat utama yang anda miliki.
Jika anda mahu ZFS membaiki dan bukan sekadar melaporkan, pool tersebut memerlukan lebih daripada satu peranti di dalam instans yang sama, dan itu adalah keputusan perancangan dan bukannya penalaan. Memilih VPS storan berbanding VPS biasa memberikan anda kapasiti, walaupun sama ada ia memberikan anda dua peranti bebas bergantung kepada pelan tersebut. Jalankan lsblk dan sahkan sebelum membina mirror pada apa yang sebenarnya merupakan dua hirisan daripada satu volum. Kami menyewakan pelayan Linux dan FreeBSD, bukan perkakas ZFS terurus, jadi jadual scrub dan sandaran adalah tanggungjawab anda untuk dijalankan. Itulah pertukarannya: kawalan penuh ke atas pool, pemilikan penuh ke atas penyelenggaraannya.
FAQ
Berapa kerap saya perlu melakukan scrub pada pool ZFS di VPS?
Kekerapan bulanan adalah memadai untuk kebanyakan pool kecil, dan ia selari dengan apa yang ditetapkan oleh pakej sedia ada: tugasan cron pada hari Ahad kedua dalam bulan di Debian dan Ubuntu, serta ambang lalai 35 hari dalam sistem berkala FreeBSD. Kekerapan mingguan hanya munasabah jika anda telah mengukur masa yang diambil untuk scrub dan mendapati ia selesai dengan cepat pada pelayan yang tidak sibuk. Pada pool yang sibuk dengan satu atau dua peranti, scrub mingguan akan menggunakan I/O aplikasi yang sebenar setiap minggu dan hanya memberikan amaran awal beberapa minggu lebih awal.
Adakah scrub pada pool ZFS cakera tunggal tidak berguna?
Tidak, selagi anda jelas tentang apa yang ia berikan kepada anda. Tanpa redundansi, scrub mengesan kerosakan tetapi tidak dapat membaikinya, kecuali bagi metadata yang mana ZFS menyimpan salinan tambahan secara lalai. Apa yang anda peroleh ialah senarai fail yang rosak dalam zpool status -v, cukup awal untuk memulihkannya sementara salinan yang baik masih wujud di tempat lain. Tindakan yang betul ialah penambahbaikan sandaran, kerana scrub memberitahu anda dengan tepat fail mana yang perlu dipulihkan.
Bolehkah saya menjeda scrub ZFS dan menyambungnya semula kemudian?
Ya. zpool scrub -p tank menjedanya, dan status jeda serta kemajuan ditulis ke cakera secara berkala, jadi scrub kekal dalam keadaan jeda walaupun selepas export atau but semula. Jalankan zpool scrub tank sekali lagi untuk menyambung semula dari pusat pemeriksaan terakhir. Jangan gunakan zpool scrub -s tank untuk tujuan ini: -s menghentikan scrub, dan scrub seterusnya akan bermula semula dari awal.
Mengapa scrub ZFS saya sangat perlahan, dan bolehkah saya mempercepatkannya?
Masa scrub bergantung pada data yang diperuntukkan dan fragmentasi, bukan kapasiti cakera. Pool yang melebihi 90% penuh adalah perlahan kerana metaslab yang mempunyai ruang kosong di bawah 4% memaksa pengumpukan (allocator) beralih daripada first-fit kepada best-fit, dan fragmentasi yang menyusul menjadikan scrub sebagai banyak bacaan kecil. Mengosongkan ruang biasanya lebih membantu berbanding sebarang pelarasan parameter. Anda boleh meningkatkan zfs_scrub_min_time_ms atau zfs_vdev_scrub_max_active untuk memberikan scrub bahagian yang lebih besar dalam baris gilir, tetapi pada pool dengan satu atau dua peranti, bahagian tersebut akan diambil terus daripada sumber aplikasi anda.