ZFS scrub zamanlaması nasıl ayarlanır?
ZFS scrub isleminin tek diskli VPS havuzlarinda veri bozulmasini nasil tespit ettigini ve sistem kaynaklarini yormadan ne siklikla calistirilmasi gerektigini ogrenin.
ZFS scrub işlemi gerçekte ne yapar
ZFS scrub, havuzdaki tüm tahsis edilmiş blokları okur, sağlama toplamlarını (checksum) yeniden hesaplar ve sonucu üst blok işaretçisinde saklanan sağlama toplamı ile karşılaştırır. İkisi uyuşmadığında, ZFS bloğu havuzun sahip olduğu yedeklilik verisini kullanarak onarır. ZFS içinde bu işi yapan başka bir mekanizma yoktur. Normal okuma işlemleri yalnızca eriştiğiniz blokları doğrular; bu nedenle iki yıldır açmadığınız bir dosya, bir scrub işlemi onu okuyana kadar doğrulanmamış kalır.
Scrub, diğer dosya sistemlerinin ihtiyaç duyduğu çevrimdışı onarım geçişi olan fsck değildir. Yapısal bir onarım aşaması yoktur çünkü ZFS, disk üzerindeki formatı hiçbir zaman bozuk bir durumda bırakmaz: her yazma işlemi yeni bir konuma gider ve havuzun kök işaretçisi olan uberblock en son güncellenir. Scrub ayrıca cihazın tamamını okumaz. Yalnızca tahsis edilmiş blokları okur; bu nedenle neredeyse boş bir havuz dakikalar içinde taranırken, %80'i dolu aynı havuz çok daha uzun sürer.
Scrub, ZFS'in sahip olduğu en düşük G/Ç önceliğinde çalışır. Linux üzerinde zfs_vdev_scrub_max_active varsayılan olarak 2'dir, bu nedenle vdev (ZFS'in tek bir birim olarak ele aldığı disk grubu) başına en fazla iki scrub okuması aynı anda yürütülür. zfs_scrub_min_time_ms varsayılan olarak 750'dir; bu, eşitleme iş parçacığının (sync thread), ZFS'in yazma işlemlerini grupladığı periyodik commit'ler olan işlem grubu temizlemeleri arasında scrub işine ayırdığı minimum süredir. Boşta duran bir makinede scrub tüm diski kullanır. Yük altındayken ise geri çekilir. Bir veya iki cihazlı bir havuzda geri çekilecek başka bir yer yoktur; bu nedenle zamanlama, altmış sürücülü büyük bir kasaya kıyasla burada çok daha önemlidir.
Kendi kendini onaramayan bir havuzu neden taramalısınız?
Küçük bir havuzda diğer her şeye karar veren cümle budur. Yedeklilik (redundancy) olmadığında, bir tarama (scrub) bozulmayı tespit eder ancak düzeltemez. Bir VPS üzerindeki tek bir sanal disk, aynalama (mirror) veya eşlik (parity) içermeyen bir havuzdur. ZFS hatalı bloğu okur, sağlama toplamı (checksum) doğrulamasını geçemez, bunu CKSUM sütununda sayar, dosyanın adını verir ve orada durur; çünkü yeniden oluşturulacak ikinci bir kopya yoktur.
Bilinmesi gereken iki kısmi istisna mevcuttur. ZFS, varsayılan olarak meta verilerin fazladan bir kopyasını redundant_metadata=all saklar ve bunu cihazın farklı bir bölgesine yazar; bu sayede tarama, tek cihazlı bir havuzda bile hasarlı bir dizin girişini veya blok işaretçisini onarabilir. Ayrıca copies=2 özelliğine sahip bir veri kümesi (dataset), veri bloklarının iki kopyasını tutar ancak bu, depolama alanının iki katına mal olur. Bunların hiçbiri, cihazın tamamen devre dışı kalması durumunda veriyi kurtaramaz. copies özelliği belgeleri tam olarak bu konuda uyarır: şeritli (striped) bir havuz oluşturup copies=2 ayarını yaparak yedekliliğe sahip olduğunuzu düşünmeyin.
Dolayısıyla tek cihazlı bir havuzda tarama size tek bir şey sağlar: erken ve doğru bildirim. Sessiz bozulmayı, yedeklerinizde dosyanın sağlam bir sürümü dururken zpool status -v içinde bir dosya adına dönüştürür. Bu, taramaya karşı bir argüman değil, yedeklemeler için bir argümandır. Eğer belirli bir ana ait görüntü (point-in-time image) ile sunucu dışındaki gerçek bir kopya arasındaki farkı netleştirmediyseniz, VPS snapshot'ının neden yedekleme sayılmadığı konusuna göz atarak başlayın; çünkü tarama sonucu yalnızca başka bir yerde sağlam bir kopyanız varsa işe yarar.
Hiçbir şey bulmayan bir tarama da bir sonuçtur. Size, güvenmek üzere olduğunuz verinin sağlam olduğunu söyler ki bir geri yükleme veya taşıma işleminden önce bilmek isteyeceğiniz şey budur.
Küçük bir VPS havuzunda ne sıklıkla scrub işlemi yapılmalıdır?
Aylık periyot doğru varsayılan değerdir ve paketlerin halihazırda kabul ettiği düzen budur. Debian ve Ubuntu, sağlıklı havuzları her ayın ikinci pazar günü scrub işleminden geçiren bir cron işi ile gelir. FreeBSD'nin periodic sistemi gün bazlı bir eşik değer üzerinden çalışır ve daily_scrub_zfs_default_threshold varsayılan olarak 35 gün değerini kullanır; kılavuz bunu beş hafta olarak tanımlar.
Yoğun çalışan küçük bir havuzda haftalık scrub işlemi, genellikle getirisinden daha fazla maliyete yol açar. Bir veya iki aygıtın bulunduğu durumlarda scrub işlemi, uygulamanızla aynı kuyruk için yarışır ve bu yükü karşılayacak boşta bir aygıt bulunmaz. Bir VPS üzerinde I/O kapasitesi sınırlıdır; dolayısıyla scrub işleminin harcadığı okuma işlemleri, veritabanınızın erişemediği okuma işlemleri anlamına gelir. Bu maliyete karşılık haftalık scrub, onaramayacağınız bir arıza hakkında size en fazla üç hafta önceden uyarı sağlar. Bu takas, yalnızca scrub işleminin maliyeti düşük olduğunda mantıklıdır.
Süreyi ölçün ve ardından karar verin. Bir kez manuel olarak scrub çalıştırın ve ne kadar sürdüğünü gözlemleyin.
sudo zpool scrub tankkomutunu sakin bir akşamda çalıştırın vezpool statusüzerinden toplam süreyi kaydedin.- İşlem bir saatin çok altında biterse ve sunucu gece boyunca boşta kalıyorsa, haftalık periyot uygulanabilir.
- Havuz trafik alırken işlem saatlerce sürüyorsa, aylık periyotta kalın ve işi paketlenmiş göreve bırakın.
- Havuz belirgin şekilde büyüdüğünde süreyi tekrar ölçün; çünkü scrub süresi disk kapasitesine değil, ayrılmış veri miktarına bağlıdır.
Hangi sıklığı seçerseniz seçin, bunu diğer düzenli sunucu işlerinizin yanına not edin. Scrub işlemi; paket yükseltmeleri ve log rotasyonu ile aynı listede yer almalıdır: bkz. aylık Linux sunucu bakım kontrol listesi.
Scrub işlemini başlatma, duraklatma ve durdurma
sudo zpool scrub tank
sudo zpool status tankDuraklatma ve durdurma birbirinden farklı işlemlerdir; yanlış olanı seçmek, saatlerce süren tekrarlı çalışmaya neden olabilir.
sudo zpool scrub -p tank
sudo zpool scrub tank
sudo zpool scrub -s tank-p işlemi duraklatır. Duraklatma durumu ve ilerleme periyodik olarak diske yazılır; bu sayede duraklatılmış bir scrub, havuzun dışa aktarılması (export) veya yeniden başlatılması durumunda korunur: havuz tekrar yüklendiğinde scrub, kaldığı yerden devam etmek üzere duraklatılmış olarak bekler. zpool scrub komutunu tekrar çalıştırmak, diske yazılan son kontrol noktasından devam etmesini sağlar. -s ise scrub işlemini tamamen durdurur ve bir sonraki scrub işlemi en baştan başlar. Diski bir saatliğine boşaltmanız gerektiğinde -p komutunu kullanın. Scrub işlemini tamamen sonlandırmak istediğinizde ise -s komutunu kullanın.
Bilinmesi gereken iki bayrak (flag) daha mevcuttur. -w, scrub işlemi bitene kadar bekler; bu, bir sonraki adımın erken başlamaması için betik (script) içerisinde kullanılması gereken yöntemdir. -e, yalnızca zpool status -v tarafından bildirilen bilinen veri hatalarına sahip dosyaları tarar; bu, yedekten geri yüklediğiniz bir dosyanın temiz olduğunu doğrulamanın hızlı yoludur.
ZFS, her havuz için aynı anda yalnızca bir scrub veya bir cihaz değişimini takiben gerçekleşen yeniden oluşturma (resilver) işlemine izin verir; çünkü her iki işlem de yoğun I/O gerektirir. Eğer bir cihaz resilver sürecindeyse, scrub işleminiz kendi sırasını bekleyecektir.
Scrub işlemi sırasında zpool durumunu okuma
sudo zpool status tank komutunu çalıştırın ve kendi sayılarınızı, başkalarının değerleriyle kıyaslamak yerine doğrudan okuyun. Bir scrub işlemi sırasında scan: satırı; taranan (scanned) miktar, gönderilen (issued) miktar, toplam miktar, onarılan (repaired) miktar, tamamlanma yüzdesi ve kalan süre tahminini içerir.
Scanned (Taranan), meta veri aşamasıdır: ZFS, blok ağacını dolaşır ve okuması gereken adresleri toplar. Issued (Gönderilen) ise veri aşamasıdır: diske gönderilen ve disk sırasına göre dizilen gerçek okuma işlemleridir. Sıralı scrub işlemi, iki farklı sayacın bulunmasının nedenidir; gerçek ilerlemeyi takip eden değer issued kısmıdır. İşlemin başlarında, scanned değeri issued değerinin çok ilerisinde gider ve süre tahmini pek anlam ifade etmez. Tahmini, ilk yüzde onluk dilimden sonra değerlendirin.
Repaired (Onarılan), sağlam bir kopyadan yeniden yazılan baytları sayar. Yedekliliği (redundancy) olmayan bir havuzda, scrub işlemi ne bulursa bulsun bu değer sıfırda kalır; bu durum, daha önce belirtilen noktanın sayısal olarak izlenebilir halidir.
Ardından cihaz bazlı sütunları okuyun. READ ve WRITE, cihazın kendi raporladığı G/Ç hatalarını sayar. CKSUM, sağlama toplamı (checksum) doğrulamasından geçemeyen blokları sayar; scrub işleminin varlık amacı da bu sütunu doldurmaktır. Sağlıklı görünen bir cihazda sıfırdan farklı bir CKSUM değeri gerçektir: veri geri dönmüştür ancak hatalı dönmüştür.
Son satır kararı gösterir. errors: No known data errors başarılı bir durumu ifade eder. Bunun dışındaki herhangi bir durum, son tam scrub işleminden bu yana oluşan veri hatalarının tam listesini (etkilenen dosya adları dahil) yazdıran sudo zpool status -v tank komutunun çalıştırılması gerektiği anlamına gelir. Bu dosyaları yedekten geri yükleyin, sayaçları sıfırlamak için sudo zpool clear tank komutunu çalıştırın ve ardından scrub işlemini tekrar başlatın. Her tam scrub işlemi bu listeyi yeniden oluşturur; dolayısıyla tam ve temiz bir scrub işleminden sonra listede görünmeyen bir dosya adı gerçekten kaybolmuş demektir.
Sisteminizde hangi periyodik scrub işi tanımlı?
Bir işin tanımlı olduğunu veya sadece bir tane olduğunu varsaymayın. Mekanizma, platforma ve pakete göre farklılık gösterir. Havuz formatı her yerde aynıdır, bu da çevresindeki araçların aynı olmadığını unutmayı kolaylaştırır; ZFS'in FreeBSD üzerinde Linux'a kıyasla nasıl sunulduğu burada önem taşıyan farktır.
FreeBSD üzerinde bu iş, periodic sisteminde yer alır. Bunları /etc/periodic.conf içinde ayarlayın:
daily_scrub_zfs_enable="YES"
daily_scrub_zfs_pools="tank"
daily_scrub_zfs_default_threshold="35"daily_scrub_zfs_pools, boşlukla ayrılmış havuz adları listesidir; boş bırakılması durumunda her havuz scrub işlemine tabi tutulur. daily_scrub_zfs_default_threshold, havuza özel bir eşik değeri ayarlanmadığında scrub işlemleri arasındaki gün sayısıdır; kılavuz varsayılan olarak 35 değerini verir. Günlük iş her gün çalışır; ancak scrub işlemini yalnızca eşik süresi dolduğunda başlatır.
Linux üzerinde durum, dağıtımınızın ZFS paketine bağlıdır ve bazı sistemler her iki mekanizmayı aynı anda barındırır. Her havuz için ayrı ayrı etkinleştirilen zfs-scrub-monthly@tank.timer ve zfs-scrub-weekly@tank.timer gibi systemd zamanlayıcıları mevcuttur. Debian ve Ubuntu ayrıca, ayın ikinci pazar günü ONLINE durumdaki tüm havuzları scrub işleminden geçiren bir betik çalıştıran /etc/cron.d/zfsutils-linux ile gelir. Yeni bir şey eklemeden önce sisteminizde ne olduğunu kontrol edin:
systemctl list-timers 'zfs-*'
ls /etc/cron.d/ | grep -i zfs
sudo zpool history tank | grep scrubzpool history en güvenilir cevaptır, çünkü havuzun gerçekten başlattığı scrub işlemlerini tarihleriyle birlikte kaydeder. Ayda iki scrub işlemi, her iki mekanizmanın da aktif olduğu anlamına gelir ve bunlardan birinin kaldırılması gerekir. Bir zamanlayıcıyı etkinleştirmek için:
sudo systemctl enable --now zfs-scrub-monthly@tank.timerBoş alan, tüm ayarlanabilir parametrelerden daha önemlidir
Küçük bir havuzdaki scrub süresi, ne kadar verinin tahsis edildiğine ve bu verinin ne kadar dağınık olduğuna bağlıdır. Havuzun dolması her iki durumu da kötüleştirir.
OpenZFS kılavuzu, havuzdaki boş alanın %10'un üzerinde tutulmasını önerir. Bu seviyenin altına düşüldüğünde, tahsis edicinin çalıştığı parçalar olan metaslab'ler %4 boş alan eşiğini aşmaya başlar ve tahsis edici "first-fit" (ilk uygun) yönteminden "best-fit" (en uygun) yöntemine geçer. "Best-fit" yöntemi çok daha fazla CPU tüketir. Yazma gecikmesi artar, parçalanma (fragmentation) başlar ve aynı miktardaki veri artık daha fazla sayıda ve daha küçük okuma işlemleriyle geldiği için bir sonraki scrub işlemi daha da yavaşlar.
Bu nedenle ilk müdahale yöntemi bir ayar değişikliği değil, veri silmektir. ZFS sistemlerinde genellikle eski snapshot'lar, ardından temizlenmemiş Docker imajları ve katmanları ve yükseltmelerden sonra geride kalan kernel paketleri yer kaplar. Başka hiçbir ayara dokunmadan önce zfs list -o space komutunu çalıştırın; bu komut, snapshot'lar tarafından tutulan alan ile canlı verinin kapladığı alanı birbirinden ayırır.
Şimdi kısaca ayarlara değinelim. Linux üzerinde mevcut değerleri şu şekilde okuyabilirsiniz:
cat /sys/module/zfs/parameters/zfs_scrub_min_time_ms
cat /sys/module/zfs/parameters/zfs_vdev_scrub_max_activeFreeBSD aynı parametreleri sysctl aracılığıyla sunar, bu yüzden kendi değerlerinizi sysctl -a | grep scrub ile bulabilirsiniz. Bu değerleri yükseltmek scrub işlemini daha hızlı bitirir ancak uygulamanızı yavaşlatır. Düşürmek ise tam tersi etki yaratır. Bir veya iki aygıttan oluşan bir havuzda, tek bir kuyruk olduğu için hiçbir ayar her iki durumu da iyileştirmez. Bir ayar, tasarım hatasını nadiren düzeltir. Eğer aylık bir scrub işlemi sistemi yoruyorsa, dürüst bir değerlendirme havuzun çok dolu olduğu veya aygıtın çok yavaş olduğu yönündedir; ayarlanabilir parametreler sorunu yalnızca başka bir yere taşır.
Scrub süresi, resilver işleminin ön izlemesidir
Bir resilver işlemi, scrub ile aynı yolu izler: ayrılmış blokları okur, doğrular ve eksik olanları yedek aygıta yazar. Bu nedenle, scrub işleminin tamamlanması için geçen süre, bir yeniden oluşturma (rebuild) işleminin ne kadar süreceğine ve bu süre zarfında havuzun ne kadar süreyle düşük yedeklilikle çalışacağına dair en gerçekçi ön izlemedir.
ZFS, resilver işlemlerini scrub işlemlerinden daha agresif bir şekilde planlar; bu nedenle bir yeniden oluşturma işlemi, aynı havuzdaki bir scrub işleminden genellikle daha kısa sürede biter. Scrub süresini ihtiyatlı bir üst sınır olarak kabul edin. Eğer scrub dokuz saat sürüyorsa, bu ölçekte bir yeniden oluşturma penceresi planlayın ve bu süre zarfında ikinci bir aygıt arızasının havuzun kaybına yol açacağını unutmayın. RAID 5 yerine kullanılan eşlik (parity) düzeni olan raidz, yeniden oluşturma sırasında hayatta kalan her aygıtı okuduğu için, tek bir geniş raidz grubu yerine yansıtılmış çiftler (mirrored pairs) kullanmanın pratik gerekçesi budur.
Tek aygıtlı bir havuzda resilver işlemi gerçekleşmez. Aygıt bozulduğunda havuz da gider. Kurtarma süreniz, geri yükleme (restore) sürenizdir; bu yüzden geri yükleme işlemini ölçün. Daha önce hiç denemediğiniz bir geri yükleme, bir kurtarma planı değildir.
Diski kiraladığınızda ne değişir
Bir VPS üzerinde blok aygıtı sanaldır. Hipervizör bir birim sunar; bunun altında yerel NVMe veya kendi eşliği (parity) olan çoğaltılmış bir ağ birimi bulunabilir. Bu durum, scrub işlemleri için iki sonuç doğurur.
Birincisi, platformun yedekliliği ZFS için görünmezdir ve ZFS bunu kullanamaz. Platform alt seviyede bir ortam hatasını onarırsa, ZFS bu sorunu asla görmez. Eğer platform hatalı bir blok iletirse, ZFS bunu yakalar ancak onaramaz; çünkü iyi kopya bu sınırın diğer tarafında kalmaktadır.
İkincisi, genellikle sanal bir diskin altındaki aygıt için SMART (kendi kendine izleme, analiz ve raporlama teknolojisi) verilerini okuyamazsınız; bu nedenle VPS üzerinde disk sağlığı izleme işleminin dayandığı erken uyarılar hiç mevcut olmayabilir. Scrub işlemlerinizden gelen CKSUM sayacı, sahip olduğunuz temel sinyal haline gelir.
ZFS'nin yalnızca raporlamak yerine onarım yapmasını istiyorsanız, havuzun aynı örnek içinde birden fazla aygıta ihtiyacı vardır ve bu bir ayar değil, planlama kararıdır. Standart bir VPS yerine depolama odaklı bir VPS seçmek size kapasite sağlar; ancak bunun size iki bağımsız aygıt sunup sunmayacağı plana bağlıdır. lsblk komutunu çalıştırın ve tek bir birimin iki dilimi olduğu ortaya çıkan bir yapı üzerinde mirror oluşturmadan önce bunu doğrulayın. Biz yönetilen bir ZFS cihazı değil, Linux ve FreeBSD sunucuları kiralıyoruz; bu nedenle scrub zamanlaması ve yedeklemeler sizin sorumluluğunuzdadır. Takas budur: havuz üzerinde tam kontrol, bakımında tam sahiplik.
FAQ
Bir VPS üzerinde ZFS havuzu ne sıklıkla taranmalıdır (scrub)?
Aylık tarama çoğu küçük havuz için uygundur ve paketlerin halihazırda yaptığı işlemle örtüşür: Debian ve Ubuntu üzerinde ikinci pazar günü çalışan bir cron işi ve FreeBSD'nin periodic sisteminde 35 günlük varsayılan eşik değeri mevcuttur. Haftalık tarama, yalnızca bir tarama işlemini zamanlayıp boş bir sunucuda hızlıca bittiğini gözlemlediyseniz makuldür. Bir veya iki aygıtlı yoğun bir havuzda, haftalık tarama her hafta gerçek uygulama G/Ç (I/O) kapasitesini tüketir ve karşılığında yalnızca birkaç haftalık erken uyarı sağlar.
Tek diskli bir ZFS havuzunu taramanın bir anlamı var mı?
Hayır, ancak size ne sağladığı konusunda net olmalısınız. Yedeklilik (redundancy) olmadığında bir tarama bozulmayı tespit eder ancak onaramaz; ZFS'nin varsayılan olarak fazladan bir kopyasını tuttuğu meta veriler bu durumun istisnasıdır. Elde ettiğiniz şey, zpool status -v içerisinde hasarlı dosyaların listesidir; bu liste, iyi bir kopyası başka bir yerde mevcutken dosyaları geri yükleyebilmeniz için yeterince erkendir. Doğru yanıt daha iyi yedekleme stratejileri uygulamaktır, çünkü tarama size tam olarak hangi dosyayı geri yüklemeniz gerektiğini söyler.
Bir ZFS taramasını duraklatıp daha sonra tamamlayabilir miyim?
Evet. zpool scrub -p tank komutu taramayı duraklatır; duraklatma durumu ve ilerleme periyodik olarak diske yazılır, bu sayede tarama bir export veya yeniden başlatma işleminden sonra da duraklatılmış halde kalır. Kaldığı yerden devam etmek için zpool scrub tank komutunu tekrar çalıştırın. Bunun için zpool scrub -s tank kullanmayın: -s taramayı tamamen durdurur ve bir sonraki tarama en baştan başlar.
ZFS taramam neden bu kadar yavaş ve hızlandırabilir miyim?
Tarama süresi disk kapasitesine değil, ayrılmış veri miktarına ve parçalanmaya (fragmentation) bağlıdır. %90'dan fazlası dolu olan bir havuz yavaştır, çünkü %4'ten az boş alanı kalan metaslab'ler ayırıcıyı (allocator) "first-fit" yönteminden "best-fit" yöntemine zorlar ve bunun sonucunda oluşan parçalanma, taramayı çok sayıda küçük okuma işlemine dönüştürür. Alan açmak genellikle herhangi bir ayarı değiştirmekten daha fazla fayda sağlar. Taramanın kuyruktan daha büyük bir pay almasını sağlamak için zfs_scrub_min_time_ms veya zfs_vdev_scrub_max_active değerlerini yükseltebilirsiniz, ancak bir veya iki aygıtlı bir havuzda bu pay doğrudan uygulamanızın performansından düşer.