SSD Nodes Learn 🎉 VPS از $5.50/ماه
راهنماها Matt Connorتوسط Matt Connor

زمان‌بندی مناسب ZFS scrub برای VPS با یک دیسک

عملیات ZFS scrub برای بررسی سلامت داده‌ها ضروری است. در یک VPS با تک دیسک، این عملیات خرابی را شناسایی اما ترمیم نمی‌کند. در اینجا بازه زمانی بهینه برای اجرا را بررسی می‌کنیم.

عملیات واقعی ZFS scrub چیست

عملیات ZFS scrub تمام بلاک‌های تخصیص‌یافته در pool را می‌خواند، checksum آن‌ها را دوباره محاسبه می‌کند و نتیجه را با checksum ذخیره‌شده در اشاره‌گر بلاک والد مقایسه می‌کند. در مواردی که این دو با هم مطابقت نداشته باشند، ZFS بلاک مذکور را با استفاده از افزونگی (redundancy) موجود در pool ترمیم می‌کند. هیچ عملیات دیگری در ZFS این وظیفه را بر عهده ندارد. خواندن‌های معمولی فقط بلاک‌هایی را تأیید می‌کنند که به آن‌ها دسترسی پیدا می‌کنید؛ بنابراین فایلی که دو سال است باز نکرده‌اید، تا زمانی که یک scrub آن را نخواند، تأییدنشده باقی می‌ماند.

عملیات scrub مشابه fsck نیست؛ یعنی آن مرحلهٔ تعمیر آفلاین که سایر سیستم‌فایل‌ها به آن نیاز دارند. در اینجا هیچ مرحلهٔ تعمیر ساختاری وجود ندارد، زیرا ZFS هرگز فرمت روی دیسک را در وضعیت خراب رها نمی‌کند: هر عملیات نوشتن به یک مکان جدید هدایت می‌شود و uberblock، که اشاره‌گر ریشهٔ pool است، در آخرین مرحله به‌روزرسانی می‌شود. همچنین scrub تمام دستگاه را نمی‌خواند. این عملیات فقط بلاک‌های تخصیص‌یافته را می‌خواند و به همین دلیل است که یک pool تقریباً خالی در عرض چند دقیقه scrub می‌شود، اما همان pool در وضعیت 80 درصد پر، زمان بسیار بیشتری می‌برد.

عملیات scrub با پایین‌ترین اولویت I/O در ZFS اجرا می‌شود. در لینوکس، مقدار zfs_vdev_scrub_max_active به‌صورت پیش‌فرض 2 است، بنابراین در هر vdev (دستگاه مجازی، گروهی از دیسک‌ها که ZFS آن‌ها را به عنوان یک واحد در نظر می‌گیرد) حداکثر دو عملیات خواندن برای scrub در لحظه در جریان است. مقدار zfs_scrub_min_time_ms به‌صورت پیش‌فرض 750 است؛ این مقدار حداقل زمانی است که thread همگام‌سازی (sync thread) بین تخلیهٔ گروه‌های تراکنش (transaction group flushes)—یعنی همان commitهای دوره‌ای که ZFS نوشتن‌ها را در آن‌ها دسته‌بندی می‌کند—صرف کار scrub می‌کند. در یک سیستم بدون بار کاری، scrub از تمام توان دیسک استفاده می‌کند. تحت بار کاری، این عملیات کنار می‌رود. در یک pool با یک یا دو دستگاه، جایی برای کنار رفتن وجود ندارد و به همین دلیل است که زمان‌بندی در اینجا اهمیت بیشتری نسبت به یک شاسی بزرگ با 60 درایو دارد.

چرا باید یک pool را که قابلیت خودترمیمی ندارد، Scrub کرد؟

این همان جمله‌ای است که تکلیف همه چیز را در یک pool کوچک مشخص می‌کند. بدون افزونگی (Redundancy)، عملیات Scrub خرابی را شناسایی می‌کند اما نمی‌تواند آن را برطرف کند. یک دیسک مجازی (Virtual Disk) در یک VPS، یک pool بدون mirror و بدون parity است. ZFS بلوک خراب را می‌خواند، در بررسی checksum شکست می‌خورد، آن را در ستون CKSUM می‌شمارد، نام فایل را اعلام می‌کند و در همان‌جا متوقف می‌شود؛ زیرا نسخه دومی برای بازسازی وجود ندارد.

دو استثنای جزئی ارزش دانستن دارند. ZFS به‌طور پیش‌فرض یک نسخه اضافی از metadata را ذخیره می‌کند (redundant_metadata=all) که در ناحیه متفاوتی از دستگاه نوشته می‌شود؛ بنابراین یک Scrub می‌تواند یک ورودی دایرکتوری یا اشاره‌گر بلوک آسیب‌دیده را حتی در یک pool تک‌دستگاهی تعمیر کند. همچنین، یک dataset با تنظیم copies=2، دو نسخه از بلوک‌های داده خود را نگه می‌دارد که هزینه فضای ذخیره‌سازی را دو برابر می‌کند. هیچ‌کدام از این‌ها در صورت از دسترس خارج شدن کامل دستگاه، کمکی نمی‌کنند. مستندات ویژگی copies دقیقاً در مورد همین موضوع هشدار می‌دهد: یک pool از نوع striped نسازید، copies=2 را فعال نکنید و تصور کنید که افزونگی دارید.

بنابراین در یک pool تک‌دستگاهی، Scrub یک مزیت به شما می‌دهد: اطلاع‌رسانی زودهنگام و دقیق. این عملیات، خرابی خاموش (Silent Corruption) را به یک نام فایل در zpool status -v تبدیل می‌کند، در حالی که نسخه سالم آن فایل هنوز در backup شما موجود است. این استدلالی برای اهمیت backup است، نه استدلالی علیه Scrub کردن. اگر هنوز تفاوت بین یک image مقطعی (Point-in-time) و یک نسخه واقعی خارج از سرور (Off-box) را مشخص نکرده‌اید، با چرا snapshot یک VPS پشتیبان محسوب نمی‌شود شروع کنید؛ زیرا نتیجه Scrub تنها زمانی مفید است که منبع دیگری یک نسخه سالم از داده‌ها را نگه داشته باشد.

Scrubی که هیچ خطایی پیدا نمی‌کند نیز یک نتیجه است. این به شما می‌گوید داده‌هایی که قصد دارید به آن‌ها اعتماد کنید سالم هستند؛ این همان چیزی است که پیش از انجام restore یا migration باید بدانید.

هر چند وقت یک‌بار باید یک pool کوچک در VPS را scrub کرد؟

حالت پیش‌فرض مناسب، ماهانه است و بسته‌های نرم‌افزاری نیز همین فرض را دارند. توزیع‌های Debian و Ubuntu یک cron job دارند که poolهای سالم را در دومین یکشنبهٔ هر ماه scrub می‌کند. سیستم periodic در FreeBSD بر اساس یک آستانهٔ زمانی به روز عمل می‌کند و مقدار پیش‌فرض daily_scrub_zfs_default_threshold برابر با 35 است که در راهنما به عنوان پنج هفته توصیف شده است.

انجام scrub به‌صورت هفتگی برای یک pool کوچک و پرمشغله، معمولاً هزینه‌اش بیش از فایده‌اش است. با داشتن یک یا دو دستگاه، عملیات scrub با صف درخواست‌های برنامهٔ شما رقابت می‌کند و دستگاه اضافه‌ای برای جذب این بار وجود ندارد. در یک VPS، سهمیهٔ I/O محدود است؛ بنابراین خواندن‌هایی که صرف scrub می‌شود، همان خواندن‌هایی است که دیتابیس شما از دست می‌دهد. در مقابل این هزینه، scrub هفتگی حداکثر سه هفته زودتر به شما دربارهٔ خطایی هشدار می‌دهد که در هر صورت قادر به تعمیر آن نیستید. این معامله تنها زمانی منطقی است که هزینهٔ scrub پایین باشد.

زمان آن را اندازه بگیرید و سپس تصمیم بگیرید. یک بار عملیات scrub را به‌صورت دستی اجرا کنید و ببینید چقدر طول می‌کشد.

  1. دستور sudo zpool scrub tank را در یک شب خلوت اجرا کنید و زمان کل را از zpool status یادداشت کنید.
  2. اگر عملیات در کمتر از یک ساعت تمام شد و سرور در طول شب بیکار است، انجام هفتگی آن مقرون‌به‌صرفه است.
  3. اگر عملیات چندین ساعت طول کشید در حالی که pool در حال سرویس‌دهی به ترافیک بود، همان حالت ماهانه را حفظ کنید و اجازه دهید job بسته‌بندی‌شده آن را مدیریت کند.
  4. هر زمان که حجم pool به‌طور قابل‌توجهی افزایش یافت، دوباره زمان‌سنجی کنید؛ زیرا مدت‌زمان scrub با داده‌های تخصیص‌یافته رابطه دارد، نه با ظرفیت دیسک.

هر چه انتخاب می‌کنید، آن را در کنار سایر کارهای دوره‌ای سرور خود یادداشت کنید. عملیات scrub باید در همان فهرستی باشد که ارتقای بسته‌ها و چرخش لاگ‌ها (log rotation) قرار دارد: به چک‌لیست ماهانه نگهداری سرور لینوکس مراجعه کنید.

شروع، توقف موقت و توقف کامل عملیات scrub

sudo zpool scrub tank
sudo zpool status tank

توقف موقت (pause) و توقف کامل (stop) دو عملیات متفاوت هستند و انتخاب اشتباه می‌تواند ساعت‌ها کار تکراری برای شما ایجاد کند.

sudo zpool scrub -p tank
sudo zpool scrub tank
sudo zpool scrub -s tank

-p عملیات را به حالت تعلیق درمی‌آورد. وضعیت و پیشرفت عملیات به‌طور دوره‌ای روی دیسک ذخیره می‌شود، بنابراین scrub معلق‌شده پس از export کردن pool یا reboot کردن سیستم باقی می‌ماند: pool با همان وضعیت scrub معلق بالا می‌آید و منتظر دستور شما می‌ماند. اجرای مجدد zpool scrub عملیات را از آخرین checkpoint ثبت‌شده روی دیسک ادامه می‌دهد. در مقابل، -s عملیات scrub را به‌طور کامل متوقف می‌کند و scrub بعدی که شروع کنید، از ابتدا آغاز خواهد شد. زمانی که برای یک ساعت به پهنای باند دیسک نیاز دارید از -p استفاده کنید. زمانی که می‌خواهید عملیات scrub کاملاً لغو شود از -s استفاده کنید.

دو فلگ دیگر نیز ارزش دانستن دارند. -w تا پایان عملیات scrub منتظر می‌ماند و سپس کنترل را بازمی‌گرداند؛ این همان چیزی است که در اسکریپت‌ها به آن نیاز دارید تا مرحلهٔ بعدی زودتر از موعد شروع نشود. -e فقط فایل‌هایی را که طبق گزارش zpool status -v دارای خطای دادهٔ شناخته‌شده هستند بررسی می‌کند؛ این سریع‌ترین راه برای اطمینان از این است که فایلی که از نسخهٔ پشتیبان بازیابی کرده‌اید، اکنون سالم است.

ZFS در هر لحظه برای هر pool تنها یک عملیات scrub یا resilver (عملیات بازسازی پس از تعویض قطعه) را اجرا می‌کند، زیرا هر دو عملیات فشار ورودی/خروجی (I/O) بالایی دارند. اگر یک قطعه در حال resilver شدن باشد، عملیات scrub شما در صف انتظار باقی می‌ماند.

نحوه خواندن وضعیت zpool در حین اجرای scrub

دستور sudo zpool status tank را اجرا کنید و اعداد خود را بخوانید؛ به جای آنکه آن‌ها را با اعداد دیگران مقایسه کنید. در حین اجرای scrub، خط scan: شامل مقدار اسکن‌شده، مقدار صادرشده، مجموع، مقدار تعمیرشده، درصد پیشرفت و تخمینی از زمان باقی‌مانده است.

Scanned مرحله متادیتای کار است: ZFS در حال پیمایش درخت بلوک‌ها و جمع‌آوری آدرس‌هایی است که باید بخواند. Issued مرحله داده است: خواندن‌هایی که واقعاً به دستگاه ارسال شده و بر اساس ترتیب دیسک مرتب شده‌اند. دلیل وجود دو شمارنده، مرتب‌سازی در scrub است و Issued همان عددی است که پیشرفت واقعی را نشان می‌دهد. در ابتدای کار، Scanned بسیار جلوتر از Issued حرکت می‌کند و تخمین زمان باقی‌مانده اعتبار چندانی ندارد. پس از گذشت ده درصد از کار، آن را قضاوت کنید.

Repaired تعداد بایت‌هایی را می‌شمارد که از روی یک کپی سالم بازنویسی شده‌اند. در یک pool بدون افزونگی (redundancy)، این عدد صرف‌نظر از آنچه scrub پیدا می‌کند، روی صفر باقی می‌ماند؛ این همان نکته‌ای است که پیش‌تر گفته شد و اکنون به صورت عددی قابل مشاهده است.

سپس ستون‌های مربوط به هر دستگاه را بخوانید. READ و WRITE تعداد خطاهای I/O گزارش‌شده توسط خود دستگاه را می‌شمارند. CKSUM بلوک‌هایی را می‌شمارد که در تایید checksum شکست خورده‌اند؛ و CKSUM ستونی است که هدف از اجرای scrub، پر کردن آن است. یک مقدار غیرصفر در CKSUM روی دستگاهی که سالم به نظر می‌رسد، واقعی است: داده بازگشته، اما به صورت نادرست بازگشته است.

خط آخر، نتیجه نهایی است. errors: No known data errors به معنای موفقیت است. هر وضعیت دیگری به معنای اجرای sudo zpool status -v tank است که لیست کامل خطاهای داده از آخرین scrub کامل، شامل نام فایل‌های آسیب‌دیده را چاپ می‌کند. آن فایل‌ها را از نسخه پشتیبان بازیابی کنید، sudo zpool clear tank را برای بازنشانی شمارنده‌ها اجرا کنید و سپس دوباره scrub را انجام دهید. هر scrub کامل، آن لیست را بازسازی می‌کند؛ بنابراین نام فایلی که پس از یک scrub کامل و تمیز در لیست نباشد، واقعاً از بین رفته است.

کدام job دوره‌ای scrub روی سیستم شما فعال است؟

فرض نکنید که حتماً یک job وجود دارد و فرض نکنید که فقط یکی از آن‌ها فعال است. مکانیزم این کار بسته به پلتفرم و بستهٔ نرم‌افزاری متفاوت است. فرمت pool در همه جا یکسان است، که باعث می‌شود فراموش کنیم ابزارهای پیرامون آن یکسان نیستند، و نحوهٔ ارائه ZFS در FreeBSD در مقایسه با Linux تفاوتی است که در اینجا اهمیت دارد.

در FreeBSD این job در سیستم periodic قرار دارد. این موارد را در /etc/periodic.conf تنظیم کنید:

daily_scrub_zfs_enable="YES"
daily_scrub_zfs_pools="tank"
daily_scrub_zfs_default_threshold="35"

daily_scrub_zfs_pools یک لیست از نام poolهاست که با فاصله از هم جدا شده‌اند؛ خالی گذاشتن آن باعث می‌شود همهٔ poolها scrub شوند. daily_scrub_zfs_default_threshold تعداد روزهای بین هر scrub در زمانی است که آستانهٔ خاصی برای pool تعیین نشده باشد، و راهنمای سیستم عدد 35 را به عنوان پیش‌فرض اعلام کرده است. این job روزانه هر روز اجرا می‌شود؛ اما تنها زمانی scrub را شروع می‌کند که آستانهٔ زمانی سپری شده باشد.

در Linux این موضوع به بستهٔ ZFS توزیع شما بستگی دارد و برخی سیستم‌ها هر دو مکانیزم را همزمان دارند. تایمرهای systemd به ازای هر pool وجود دارند، یعنی zfs-scrub-monthly@tank.timer و zfs-scrub-weekly@tank.timer، که هر بار برای یک pool فعال می‌شوند. دبیان و اوبونتو همچنین /etc/cron.d/zfsutils-linux را ارائه می‌دهند که اسکریپتی را اجرا می‌کند که در دومین یکشنبهٔ هر ماه، تمام poolهای ONLINE را scrub می‌کند. پیش از افزودن هر چیزی، بررسی کنید چه چیزی در اختیار دارید:

systemctl list-timers 'zfs-*'
ls /etc/cron.d/ | grep -i zfs
sudo zpool history tank | grep scrub

zpool history پاسخ دقیق است، زیرا scrubهایی که واقعاً توسط pool شروع شده‌اند را به همراه تاریخ ثبت می‌کند. دو بار scrub در ماه به این معنی است که هر دو مکانیزم فعال هستند و باید یکی از آن‌ها حذف شود. برای فعال‌سازی یک تایمر:

sudo systemctl enable --now zfs-scrub-monthly@tank.timer

فضای آزاد از هر پارامتر تنظیمی مهم‌تر است

مدت زمان اسکراب (scrub) در یک pool کوچک، به میزان داده‌های تخصیص‌یافته و میزان پراکندگی آن‌ها بستگی دارد. پر کردن pool هر دو عامل را تشدید می‌کند.

توصیه OpenZFS این است که فضای آزاد pool را بالای 10% نگه دارید. زیر این مقدار، metaslabها (بخش‌هایی که تخصیص‌دهنده با آن‌ها کار می‌کند) از آستانه 4% فضای آزاد عبور می‌کنند و تخصیص‌دهنده از حالت first-fit به best-fit تغییر وضعیت می‌دهد. حالت best-fit به مراتب پردازش CPU بیشتری می‌طلبد. تأخیر نوشتن افزایش می‌یابد، قطعه‌قطعه شدن (fragmentation) رخ می‌دهد و اسکراب بعدی حتی کندتر می‌شود، زیرا همان مقدار داده اکنون در قالب تعداد بیشتری خواندنِ کوچک‌تر انجام می‌شود.

بنابراین، اولین اهرم، یک پارامتر تنظیمی نیست؛ بلکه حذف کردن داده‌هاست. اسنپ‌شات‌های قدیمی معمول‌ترین دلیل در سیستم‌های ZFS هستند و پس از آن ایمیج‌ها و لایه‌های Docker که پاک‌سازی نشده‌اند و پکیج‌های کرنل که پس از ارتقا باقی مانده‌اند قرار دارند. پیش از دست زدن به هر چیز دیگری، zfs list -o space را اجرا کنید، زیرا فضای اشغال‌شده توسط اسنپ‌شات‌ها را از فضای داده‌های زنده تفکیک می‌کند.

سپس، به طور خلاصه به سراغ تنظیمات می‌رویم. در لینوکس می‌توانید مقادیر فعلی را بخوانید:

cat /sys/module/zfs/parameters/zfs_scrub_min_time_ms
cat /sys/module/zfs/parameters/zfs_vdev_scrub_max_active

سیستم‌عامل FreeBSD همین پارامترها را از طریق sysctl ارائه می‌دهد، بنابراین پارامترهای خود را با sysctl -a | grep scrub پیدا کنید. افزایش آن‌ها باعث می‌شود اسکراب زودتر تمام شود اما سرعت برنامه شما کاهش یابد. کاهش آن‌ها نتیجه معکوس دارد. در یک pool با یک یا دو دستگاه، هیچ تنظیمی نمی‌تواند هر دو را بهبود بخشد، زیرا تنها یک صف برای تقسیم وجود دارد. یک پارامتر تنظیمی به‌ندرت یک مشکل طراحی را حل می‌کند. اگر اسکراب ماهانه باعث ایجاد مشکل می‌شود، واقعیت این است که pool بیش از حد پر شده یا دستگاه بیش از حد کند است و یک پارامتر تنظیمی فقط صورت‌مسئله را جابه‌جا می‌کند.

زمان Scrub پیش‌نمایشی از مدت‌زمان Resilver است

عملیات Resilver همان مسیری را طی می‌کند که یک Scrub طی می‌کند: بلوک‌های تخصیص‌یافته را می‌خواند، آن‌ها را تأیید می‌کند و بلوک‌های مفقود را روی دستگاه جایگزین می‌نویسد. بنابراین، زمانی که عملیات Scrub شما می‌گیرد، دقیق‌ترین پیش‌نمایش صادقانه از مدت‌زمان بازسازی (Rebuild) و همچنین مدت‌زمانی است که Pool شما در طول این فرایند با افزونگی (Redundancy) کاهش‌یافته کار خواهد کرد.

ZFS کارِ Resilver را تهاجمی‌تر از کارِ Scrub زمان‌بندی می‌کند، بنابراین بازسازی معمولاً سریع‌تر از Scrub همان Pool به پایان می‌رسد. زمان Scrub خود را به عنوان یک حد بالای محافظه‌کارانه در نظر بگیرید. اگر Scrub نه ساعت طول می‌کشد، برای یک بازه زمانی بازسازی در همان حدود برنامه‌ریزی کنید و در نظر داشته باشید که خرابی دستگاه دوم در این بازه، منجر به از دست رفتن کل Pool می‌شود. این استدلال عملی برای استفاده از جفت‌های Mirror به‌جای یک گروه Raidz بزرگ است، زیرا Raidz که طرح‌بندی مبتنی بر Parity در ZFS و جایگزین RAID 5 است، با خواندن تمام دستگاه‌های سالم بازسازی می‌شود.

در یک Pool تک‌دستگاهی، اصلاً عملیات Resilver وجود ندارد. دستگاه از کار می‌افتد و Pool نیز همراه با آن از بین می‌رود. زمان بازیابی شما در اینجا همان زمان Restore است، بنابراین به جای آن، Restore را اندازه‌گیری کنید. Restoreای که هرگز آن را اجرا نکرده‌اید، یک طرح بازیابی محسوب نمی‌شود.

تغییرات هنگام اجاره دیسک

در یک VPS، دستگاه بلاک (block device) مجازی است. هایپروایزر یک volume ارائه می‌دهد و در لایه زیرین آن ممکن است یک حافظه NVMe محلی یا یک volume شبکه‌ای با قابلیت parity اختصاصی وجود داشته باشد. این موضوع دو پیامد برای عملیات scrub به همراه دارد.

نخست، افزونگی (redundancy) پلتفرم برای ZFS نامرئی است و ZFS نمی‌تواند از آن استفاده کند. اگر پلتفرم یک خطای رسانه را در لایه زیرین شما ترمیم کند، ZFS هرگز متوجه آن مشکل نمی‌شود. اگر پلتفرم یک بلاک اشتباه را به لایه بالاتر تحویل دهد، ZFS آن را شناسایی می‌کند اما قادر به اصلاح آن نیست، زیرا نسخه سالم در آن سوی مرز مجازی قرار دارد.

دوم، شما معمولاً نمی‌توانید داده‌های SMART (فناوری خود-نظارتی، تحلیل و گزارش‌دهی) را برای دستگاه زیرین یک دیسک مجازی بخوانید؛ بنابراین هشدارهای اولیه‌ای که پایش سلامت دیسک در VPS به آن‌ها وابسته است، ممکن است اصلاً در دسترس نباشند. شمارنده CKSUM حاصل از عملیات scrub، به اصلی‌ترین سیگنال در اختیار شما تبدیل می‌شود.

اگر می‌خواهید ZFS به جای گزارش‌دهی صرف، عملیات ترمیم را نیز انجام دهد، pool شما به بیش از یک دستگاه در داخل همان instance نیاز دارد و این یک تصمیم در سطح طراحی است، نه یک تنظیم ساده. انتخاب یک VPS ذخیره‌سازی به جای یک VPS معمولی ظرفیت مورد نیاز را برای شما فراهم می‌کند، هرچند اینکه آیا واقعاً دو دستگاه مستقل دریافت می‌کنید یا خیر، به طرح انتخابی بستگی دارد. پیش از ساخت یک mirror روی چیزی که ممکن است در نهایت دو برش از یک volume واحد باشد، دستور lsblk را اجرا کرده و وضعیت را تأیید کنید. ما سرورهای Linux و FreeBSD اجاره می‌دهیم، نه یک دستگاه ZFS مدیریت‌شده؛ بنابراین زمان‌بندی scrub و تهیه نسخه‌های پشتیبان بر عهده شماست. این همان معامله است: کنترل کامل بر pool و مسئولیت کامل نگهداری آن.

FAQ

هر چند وقت یک‌بار باید یک ZFS pool را روی VPS اسکراب (scrub) کنم؟

برای اکثر poolهای کوچک، بازهٔ ماهانه مناسب است و با تنظیمات پیش‌فرض بسته‌ها نیز مطابقت دارد: یک job در cron که در دومین یکشنبهٔ هر ماه در Debian و Ubuntu اجرا می‌شود، و یک آستانهٔ 35 روزه در سیستم periodic در FreeBSD. اسکراب هفتگی تنها زمانی منطقی است که زمان اسکراب را اندازه‌گیری کرده باشید و دیده باشید که روی یک سیستم بدون بار، سریع تمام می‌شود. در یک pool پرمشغله با یک یا دو دستگاه، اسکراب هفتگی هر هفته بخشی از I/O واقعی برنامه را اشغال می‌کند و تنها چند هفته زودتر به شما هشدار می‌دهد.

آیا اسکراب کردن یک ZFS pool تک‌دیسکی بی‌فایده است؟

خیر، به شرطی که بدانید این کار چه دستاوردی دارد. بدون افزونگی (redundancy)، اسکراب خرابی را تشخیص می‌دهد اما نمی‌تواند آن را تعمیر کند؛ مگر در مورد متادیتا که ZFS به‌طور پیش‌فرض یک نسخهٔ اضافی از آن را نگه می‌دارد. آنچه به دست می‌آورید، فهرستی از فایل‌های آسیب‌دیده در zpool status -v است که آن‌قدر زود به دست می‌آید که می‌توانید پیش از از دست رفتن کامل، آن‌ها را از جای دیگری بازیابی کنید. واکنش درست، بهبود سیستم پشتیبان‌گیری است، زیرا اسکراب دقیقاً به شما می‌گوید کدام فایل نیاز به بازیابی دارد.

آیا می‌توانم اسکراب ZFS را متوقف (pause) کنم و بعداً ادامه دهم؟

بله. دستور zpool scrub -p tank آن را متوقف می‌کند و وضعیت توقف و پیشرفت کار به‌طور دوره‌ای روی دیسک نوشته می‌شود، بنابراین اسکراب در صورت export کردن یا reboot سیستم، در حالت توقف باقی می‌ماند. برای ادامه از آخرین checkpoint، دوباره zpool scrub tank را اجرا کنید. برای این کار از zpool scrub -s tank استفاده نکنید: -s اسکراب را متوقف (stop) می‌کند و دفعهٔ بعد، اسکراب از ابتدا شروع خواهد شد.

چرا اسکراب ZFS من بسیار کند است و آیا می‌توانم سرعت آن را افزایش دهم؟

زمان اسکراب به میزان داده‌های تخصیص‌یافته و پراکندگی (fragmentation) بستگی دارد، نه ظرفیت دیسک. یک pool که بیش از 90 درصد آن پر شده باشد، کند عمل می‌کند زیرا metaslabهایی که کمتر از 4 درصد فضای خالی دارند، تخصیص‌دهنده (allocator) را از حالت first-fit به best-fit تغییر می‌دهند و پراکندگی حاصل از آن، اسکراب را به تعداد زیادی عملیات خواندن کوچک تبدیل می‌کند. آزادسازی فضا معمولاً بیش از هر تنظیم دیگری کمک می‌کند. می‌توانید zfs_scrub_min_time_ms یا zfs_vdev_scrub_max_active را افزایش دهید تا سهم بزرگ‌تری از صف به اسکراب اختصاص یابد، اما در یک pool با یک یا دو دستگاه، این سهم مستقیماً از توان پردازشی برنامهٔ شما کسر می‌شود.