ตั้งค่า ZFS scrub สำหรับ VPS ที่มีดิสก์ลูกเดียวอย่างไร
การทำ ZFS scrub บน VPS ที่ใช้ดิสก์เดี่ยวช่วยตรวจสอบความสมบูรณ์ของข้อมูลได้ แม้จะไม่สามารถซ่อมแซมได้หากพบความเสียหาย แต่การตั้งค่าให้รันเดือนละครั้งถือว่าเหมาะสมที่สุด
การทำงานจริงของ ZFS scrub
ZFS scrub จะอ่านทุกบล็อกที่มีการจัดสรรไว้ใน pool คำนวณค่า checksum ใหม่ แล้วนำไปเปรียบเทียบกับค่า checksum ที่เก็บไว้ใน parent block pointer หากค่าทั้งสองไม่ตรงกัน ZFS จะซ่อมแซมบล็อกนั้นโดยใช้ข้อมูลสำรองที่มีอยู่ใน pool ไม่มีกระบวนการอื่นใดใน ZFS ที่ทำหน้าที่นี้ การอ่านข้อมูลตามปกติจะตรวจสอบเฉพาะบล็อกที่คุณเข้าถึงเท่านั้น ดังนั้นไฟล์ที่คุณไม่ได้เปิดใช้งานมาเป็นเวลาสองปีจะยังไม่ได้รับการตรวจสอบจนกว่า scrub จะอ่านไฟล์นั้น
การทำ scrub ไม่ใช่ fsck ซึ่งเป็นขั้นตอนการซ่อมแซมแบบออฟไลน์ที่ระบบไฟล์อื่นจำเป็นต้องใช้ เนื่องจากไม่มีขั้นตอนการซ่อมแซมโครงสร้าง เพราะ ZFS ไม่เคยปล่อยให้รูปแบบข้อมูลบนดิสก์อยู่ในสถานะเสียหาย การเขียนข้อมูลทุกครั้งจะถูกส่งไปยังตำแหน่งใหม่ และ uberblock ซึ่งเป็น root pointer ของ pool จะถูกอัปเดตเป็นลำดับสุดท้าย นอกจากนี้ scrub จะไม่อ่านข้อมูลทั้งอุปกรณ์ แต่จะอ่านเฉพาะบล็อกที่มีการจัดสรรไว้เท่านั้น นี่คือเหตุผลว่าทำไม pool ที่เกือบว่างเปล่าจึงใช้เวลา scrub เพียงไม่กี่นาที ในขณะที่ pool เดียวกันที่มีข้อมูลเต็ม 80% จะใช้เวลานานกว่ามาก
การทำ scrub จะทำงานที่ลำดับความสำคัญของ I/O ต่ำที่สุดที่ ZFS มี บน Linux ค่า zfs_vdev_scrub_max_active จะถูกตั้งค่าเริ่มต้นไว้ที่ 2 ดังนั้นจะมี scrub read ทำงานพร้อมกันได้สูงสุดเพียงสองรายการต่อหนึ่ง vdev (virtual device คือกลุ่มของดิสก์ที่ ZFS มองว่าเป็นหน่วยเดียวกัน) ค่า zfs_scrub_min_time_ms จะถูกตั้งค่าเริ่มต้นไว้ที่ 750 ซึ่งเป็นเวลาขั้นต่ำที่ sync thread จะใช้ทำงาน scrub ระหว่างการ flush transaction group ซึ่งเป็นการ commit ข้อมูลที่ ZFS รวบรวมไว้เป็นชุดๆ ในเครื่องที่ไม่มีภาระงาน scrub จะใช้ประสิทธิภาพของดิสก์ทั้งหมด แต่เมื่อมีภาระงาน scrub จะลดลำดับความสำคัญลง ใน pool ที่มีอุปกรณ์เพียงหนึ่งหรือสองตัว จะไม่มีพื้นที่ให้หลีกเลี่ยงภาระงานได้มากนัก นี่คือเหตุผลว่าทำไมการจัดตารางเวลาจึงมีความสำคัญมากกว่าในกรณีนี้ เมื่อเทียบกับแชสซีขนาดใหญ่ที่มีดิสก์จำนวนหกสิบลูก
เหตุใดจึงต้องทำ scrub ใน pool ที่ไม่สามารถซ่อมแซมตัวเองได้?
นี่คือประโยคตัดสินใจสำหรับ pool ขนาดเล็ก หากไม่มีการทำ redundancy การทำ scrub จะตรวจพบความเสียหายแต่ไม่สามารถแก้ไขได้ virtual disk เพียงตัวเดียวใน VPS ถือเป็น pool ที่ไม่มีการทำ mirror และไม่มี parity ระบบ ZFS จะอ่านบล็อกที่เสียหาย ตรวจสอบ checksum ไม่ผ่าน แล้วนับจำนวนในคอลัมน์ CKSUM พร้อมระบุชื่อไฟล์ที่ได้รับผลกระทบ จากนั้นจะหยุดการทำงานเนื่องจากไม่มีสำเนาที่สองสำหรับใช้กู้คืนข้อมูล
มีข้อยกเว้นบางประการที่ควรทราบ ZFS จะจัดเก็บสำเนา metadata เพิ่มเติมไว้โดยค่าเริ่มต้น (redundant_metadata=all) ซึ่งจะถูกเขียนลงในส่วนอื่นของอุปกรณ์ ดังนั้นการทำ scrub จึงสามารถซ่อมแซม directory entry หรือ block pointer ที่เสียหายได้แม้จะเป็น pool ที่มีอุปกรณ์เพียงตัวเดียว นอกจากนี้ dataset ที่ตั้งค่า copies=2 จะเก็บสำเนาของบล็อกข้อมูลไว้สองชุดโดยแลกกับพื้นที่จัดเก็บที่เพิ่มขึ้นเป็นสองเท่า แต่ทั้งสองกรณีนี้ไม่สามารถกู้คืนข้อมูลได้หากอุปกรณ์นั้นสูญหายไป เอกสารประกอบคุณสมบัติ copies ได้เตือนไว้ชัดเจนว่า: อย่าสร้าง striped pool แล้วตั้งค่า copies=2 โดยเชื่อว่าคุณมี redundancy แล้ว
ดังนั้น ใน pool ที่มีอุปกรณ์เพียงตัวเดียว การทำ scrub จะให้ผลลัพธ์อย่างหนึ่งคือ: การแจ้งเตือนที่รวดเร็วและแม่นยำ มันจะเปลี่ยนความเสียหายที่ตรวจไม่พบให้กลายเป็นชื่อไฟล์ใน zpool status -v ในขณะที่ระบบสำรองข้อมูลของคุณยังคงเก็บไฟล์เวอร์ชันที่สมบูรณ์ไว้ นี่เป็นเหตุผลที่สนับสนุนการสำรองข้อมูล ไม่ใช่เหตุผลที่คัดค้านการทำ scrub หากคุณยังไม่เข้าใจความแตกต่างระหว่าง point-in-time image กับสำเนาที่เก็บไว้นอกเซิร์ฟเวอร์จริงๆ ให้เริ่มอ่านจาก เหตุใด VPS snapshot จึงไม่ใช่การสำรองข้อมูล เพราะผลลัพธ์จากการทำ scrub จะมีประโยชน์ก็ต่อเมื่อมีแหล่งข้อมูลอื่นที่เก็บสำเนาที่สมบูรณ์ไว้เท่านั้น
การทำ scrub แล้วไม่พบสิ่งผิดปกติก็ถือเป็นผลลัพธ์เช่นกัน มันบอกให้คุณทราบว่าข้อมูลที่คุณกำลังจะใช้งานนั้นยังคงสมบูรณ์ ซึ่งเป็นสิ่งที่คุณควรตรวจสอบก่อนการกู้คืนหรือการย้ายข้อมูล
ควรตรวจสอบความสมบูรณ์ของข้อมูล (scrub) ในกลุ่ม VPS ขนาดเล็กบ่อยแค่ไหน?
การตรวจสอบเป็นรายเดือนเป็นค่าเริ่มต้นที่เหมาะสม และเป็นสิ่งที่แพ็กเกจต่างๆ กำหนดไว้แล้ว Debian และ Ubuntu มี cron job ที่ทำหน้าที่ตรวจสอบ pool ที่อยู่ในสถานะปกติในวันอาทิตย์ที่สองของทุกเดือน ระบบ periodic ของ FreeBSD ทำงานโดยอิงจากเกณฑ์จำนวนวัน ซึ่ง daily_scrub_zfs_default_threshold กำหนดค่าเริ่มต้นไว้ที่ 35 วัน ตามที่ระบุไว้ในคู่มือว่าเป็นเวลาห้าสัปดาห์
การตรวจสอบรายสัปดาห์สำหรับ pool ขนาดเล็กที่มีการใช้งานสูงมักไม่คุ้มค่ากับทรัพยากรที่เสียไป ในกรณีที่มีอุปกรณ์เพียงหนึ่งหรือสองตัว การทำ scrub จะแย่งคิวการทำงานกับแอปพลิเคชันของคุณ และไม่มีอุปกรณ์สำรองที่จะช่วยแบ่งเบาภาระงานได้ บน VPS นั้นปริมาณ I/O มีจำกัด ดังนั้นการอ่านข้อมูลที่ใช้ไปกับการทำ scrub คือการอ่านที่ฐานข้อมูลของคุณจะไม่ได้ใช้งาน เมื่อเทียบกับต้นทุนดังกล่าว การตรวจสอบรายสัปดาห์จะช่วยให้คุณทราบถึงความผิดปกติที่แก้ไขไม่ได้อยู่ดีเร็วขึ้นเพียงไม่เกินสามสัปดาห์เท่านั้น การแลกเปลี่ยนนี้จะสมเหตุสมผลก็ต่อเมื่อการทำ scrub นั้นใช้ทรัพยากรน้อย
ให้วัดเวลาที่ใช้แล้วจึงตัดสินใจ ลองทำ scrub ด้วยตนเองหนึ่งครั้งและสังเกตว่าใช้เวลานานเท่าใด
- รัน
sudo zpool scrub tankในช่วงเย็นที่ไม่มีการใช้งานและบันทึกเวลาทั้งหมดจากzpool status - หากการทำงานเสร็จสิ้นภายในเวลาไม่ถึงหนึ่งชั่วโมงและเซิร์ฟเวอร์ว่างในช่วงกลางคืน การตรวจสอบรายสัปดาห์ถือว่าทำได้
- หากการทำงานใช้เวลาหลายชั่วโมงในขณะที่ pool กำลังให้บริการ traffic ให้คงการตรวจสอบเป็นรายเดือนไว้และปล่อยให้เป็นหน้าที่ของงานที่มากับแพ็กเกจ
- วัดเวลาใหม่ทุกครั้งที่ขนาดของ pool เพิ่มขึ้นอย่างเห็นได้ชัด เพราะระยะเวลาในการทำ scrub ขึ้นอยู่กับปริมาณข้อมูลที่ถูกจัดสรร ไม่ใช่ความจุของดิสก์
ไม่ว่าคุณจะเลือกแบบใด ให้จดบันทึกไว้คู่กับงานดูแลเซิร์ฟเวอร์ประจำอื่นๆ ของคุณ การทำ scrub ควรอยู่ในรายการเดียวกับการอัปเกรดแพ็กเกจและการหมุนเวียน log: ดูที่ รายการตรวจสอบการบำรุงรักษาเซิร์ฟเวอร์ Linux รายเดือน
การเริ่ม การหยุดชั่วคราว และการหยุดการทำ scrub
sudo zpool scrub tank
sudo zpool status tankการหยุดชั่วคราวและการหยุดการทำงานเป็นคนละกระบวนการกัน การเลือกใช้คำสั่งผิดอาจทำให้คุณต้องเสียเวลาทำงานซ้ำนานหลายชั่วโมง
sudo zpool scrub -p tank
sudo zpool scrub tank
sudo zpool scrub -s tank-p ใช้สำหรับหยุดชั่วคราว สถานะและคืบหน้าของการ scrub จะถูกบันทึกลงดิสก์เป็นระยะ ดังนั้นการ scrub ที่ถูกหยุดชั่วคราวจะยังคงอยู่แม้จะมีการ export pool หรือรีบูตเครื่อง เมื่อ pool กลับมาออนไลน์ สถานะการ scrub จะยังคงค้างอยู่ที่เดิมเพื่อรอให้คุณดำเนินการต่อ การรัน zpool scrub อีกครั้งจะเป็นการเริ่มทำงานต่อจากจุดตรวจสอบล่าสุดที่บันทึกไว้ในดิสก์ ส่วน -s จะเป็นการหยุดการ scrub โดยสมบูรณ์ และการ scrub ครั้งถัดไปจะเริ่มต้นใหม่ตั้งแต่ต้น ให้ใช้ -p เมื่อคุณต้องการคืนทรัพยากรดิสก์ชั่วคราวสักหนึ่งชั่วโมง และใช้ -s เมื่อคุณต้องการยกเลิกการ scrub นั้นไปเลย
มีอีกสอง flag ที่ควรทราบ -w จะรอจนกว่าการ scrub จะเสร็จสิ้นจึงจะคืนค่าคำสั่ง ซึ่งเป็นสิ่งที่ควรใช้ภายในสคริปต์เพื่อให้แน่ใจว่าขั้นตอนถัดไปจะไม่เริ่มทำงานก่อนเวลา ส่วน -e จะทำการ scrub เฉพาะไฟล์ที่พบข้อผิดพลาดของข้อมูลตามที่รายงานโดย zpool status -v ซึ่งเป็นวิธีที่รวดเร็วในการตรวจสอบว่าไฟล์ที่คุณกู้คืนจากข้อมูลสำรองนั้นสะอาดแล้ว
ZFS จะรันการ scrub หรือ resilver (กระบวนการสร้างข้อมูลใหม่หลังเปลี่ยนอุปกรณ์) ได้เพียงอย่างละหนึ่งรายการต่อหนึ่ง pool ในเวลาเดียวกัน เนื่องจากทั้งสองกระบวนการใช้ I/O สูง หากอุปกรณ์กำลังทำ resilver อยู่ การ scrub ของคุณจะต้องรอคิวจนกว่าจะถึงรอบของมัน
วิธีอ่านสถานะ zpool ขณะที่ scrub กำลังทำงาน
ให้รัน sudo zpool status tank และอ่านตัวเลขของคุณเอง แทนที่จะนำไปเปรียบเทียบกับของผู้อื่น ในระหว่างการ scrub บรรทัด scan: จะแสดงตัวเลขที่สแกนไปแล้ว (scanned), ตัวเลขที่ส่งคำสั่งอ่านแล้ว (issued), ยอดรวมทั้งหมด (total), ตัวเลขที่ซ่อมแซมแล้ว (repaired), เปอร์เซ็นต์ที่เสร็จสิ้น และเวลาที่คาดว่าจะเหลืออยู่
Scanned คือขั้นตอนการตรวจสอบ metadata: ZFS จะไล่ดูโครงสร้าง block tree และรวบรวมที่อยู่ของข้อมูลที่จำเป็นต้องอ่าน Issued คือขั้นตอนการจัดการข้อมูล: คือการอ่านที่ถูกส่งไปยังอุปกรณ์จริง โดยมีการจัดเรียงลำดับตามตำแหน่งของดิสก์ การ scrub แบบจัดเรียงลำดับเป็นเหตุผลว่าทำไมจึงมีตัวนับสองชุด และ issued คือตัวที่ใช้ติดตามความคืบหน้าจริง ในช่วงแรกค่า scanned จะนำหน้า issued ไปไกลและค่าเวลาที่คาดการณ์ไว้จะยังไม่มีความหมายมากนัก ให้ประเมินหลังจากผ่านไปแล้วสิบเปอร์เซ็นต์
Repaired คือจำนวนไบต์ที่ถูกเขียนใหม่จากสำเนาที่ถูกต้อง ใน pool ที่ไม่มี redundancy ค่านี้จะคงอยู่ที่ศูนย์ไม่ว่า scrub จะพบอะไรก็ตาม ซึ่งเป็นการย้ำประเด็นก่อนหน้านี้ในรูปแบบตัวเลขที่คุณสามารถเฝ้าสังเกตได้
จากนั้นให้อ่านคอลัมน์แยกตามอุปกรณ์แต่ละตัว READ และ WRITE คือจำนวนข้อผิดพลาด I/O ที่อุปกรณ์รายงานออกมาเอง CKSUM คือจำนวน block ที่ไม่ผ่านการตรวจสอบ checksum และ CKSUM คือคอลัมน์ที่การ scrub มีไว้เพื่อตรวจสอบ หากพบค่า CKSUM ที่ไม่ใช่ศูนย์บนอุปกรณ์ที่ดูเหมือนปกติ นั่นคือปัญหาจริง: ข้อมูลถูกส่งกลับมาแล้ว แต่เป็นข้อมูลที่ผิดพลาด
บรรทัดสุดท้ายคือบทสรุป errors: No known data errors หมายถึงผ่าน หากเป็นค่าอื่นหมายความว่าคุณต้องรัน sudo zpool status -v tank ซึ่งจะแสดงรายการข้อผิดพลาดของข้อมูลทั้งหมดตั้งแต่การ scrub ครั้งล่าสุดที่สมบูรณ์ รวมถึงชื่อไฟล์ที่ได้รับผลกระทบ ให้กู้คืนไฟล์เหล่านั้นจากข้อมูลสำรอง รัน sudo zpool clear tank เพื่อรีเซ็ตตัวนับ แล้วทำการ scrub อีกครั้ง การ scrub ที่สมบูรณ์แต่ละครั้งจะสร้างรายการนั้นขึ้นมาใหม่ ดังนั้นหากชื่อไฟล์หายไปหลังจาก scrub จนสะอาดหมดจดแล้ว แสดงว่าไฟล์นั้นสูญหายไปอย่างถาวรแล้วจริง ๆ
งาน scrub แบบเป็นรอบที่อยู่ในเครื่องของคุณคืออะไร
อย่าทึกทักเอาเองว่ามีงานดังกล่าวอยู่ และอย่าทึกทักว่ามีเพียงงานเดียว กลไกการทำงานนั้นแตกต่างกันไปตามแพลตฟอร์มและแพ็กเกจ รูปแบบของ pool นั้นเหมือนกันทุกที่ ซึ่งทำให้ลืมไปได้ง่ายว่าเครื่องมือที่ใช้จัดการนั้นไม่เหมือนกัน และ วิธีการที่ ZFS ถูกจัดส่งบน FreeBSD เมื่อเทียบกับ Linux คือความแตกต่างที่สำคัญในกรณีนี้
บน FreeBSD งานจะอยู่ในระบบ 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 ที่คั่นด้วยช่องว่าง หากปล่อยว่างไว้จะเป็นการ scrub ทุก pool ส่วน daily_scrub_zfs_default_threshold คือจำนวนวันระหว่างการ scrub ในกรณีที่ไม่ได้ตั้งค่า threshold เฉพาะสำหรับ pool นั้นๆ โดยคู่มือระบุค่าเริ่มต้นไว้ที่ 35 งานรายวันจะทำงานทุกวัน แต่จะเริ่มการ scrub ก็ต่อเมื่อครบกำหนด threshold แล้วเท่านั้น
บน Linux จะขึ้นอยู่กับแพ็กเกจ ZFS ของดิสทริบิวชันที่คุณใช้ และบางระบบอาจมีกลไกทั้งสองแบบทำงานพร้อมกัน โดยจะมี systemd timer แยกตามแต่ละ pool คือ zfs-scrub-monthly@tank.timer และ zfs-scrub-weekly@tank.timer ซึ่งเปิดใช้งานทีละ pool นอกจากนี้ Debian และ Ubuntu ยังมี /etc/cron.d/zfsutils-linux ซึ่งจะรันสคริปต์เพื่อ scrub ทุก pool ที่มีสถานะ ONLINE ในวันอาทิตย์ที่สองของเดือน ให้ตรวจสอบสิ่งที่คุณมีก่อนที่จะเพิ่มรายการใดๆ:
systemctl list-timers 'zfs-*'
ls /etc/cron.d/ | grep -i zfs
sudo zpool history tank | grep scrubzpool history คือคำตอบที่ตรงไปตรงมาที่สุด เพราะมันจะบันทึกการ scrub ที่ pool ได้เริ่มทำงานจริงพร้อมระบุวันที่ หากมีการ scrub สองครั้งต่อเดือน แสดงว่ากลไกทั้งสองแบบกำลังทำงานอยู่และควรปิดการทำงานไปหนึ่งอย่าง หากต้องการเปิดใช้งาน timer ให้ใช้คำสั่ง:
sudo systemctl enable --now zfs-scrub-monthly@tank.timerพื้นที่ว่างมีความสำคัญมากกว่าการปรับแต่งค่าใดๆ
ระยะเวลาในการทำ scrub บน pool ขนาดเล็กถูกกำหนดโดยปริมาณข้อมูลที่ถูกจัดสรรไว้และความกระจัดกระจายของข้อมูลนั้น การทำให้ pool เต็มจะส่งผลเสียต่อทั้งสองปัจจัย
คำแนะนำของ OpenZFS คือให้รักษาพื้นที่ว่างใน pool ไว้เหนือ 10% หากต่ำกว่านั้น metaslabs ซึ่งเป็นส่วนของข้อมูลที่ตัวจัดสรร (allocator) ทำงานด้วย จะเริ่มข้ามเกณฑ์พื้นที่ว่าง 4% และตัวจัดสรรจะเปลี่ยนจากการทำงานแบบ first-fit ไปเป็น best-fit ซึ่งการทำงานแบบ best-fit นั้นใช้ CPU สูงกว่ามาก ส่งผลให้ write latency เพิ่มขึ้น ตามมาด้วยปัญหา fragmentation และการทำ scrub ในครั้งถัดไปจะยิ่งช้าลง เนื่องจากข้อมูลจำนวนเท่าเดิมจะถูกอ่านในรูปแบบที่กระจัดกระจายและมีขนาดเล็กลง
ดังนั้น วิธีการแรกจึงไม่ใช่การปรับแต่งค่า แต่คือการลบข้อมูลที่ไม่จำเป็นออก Snapshot เก่ามักเป็นสาเหตุหลักบนเครื่อง ZFS ตามมาด้วย Docker images และ layers ที่ไม่ได้ถูกลบ และ kernel packages ที่ตกค้างจากการอัปเกรด ให้รัน zfs list -o space ก่อนที่คุณจะดำเนินการใดๆ เพราะคำสั่งนี้จะแยกพื้นที่ที่ถูกจองโดย snapshot ออกจากพื้นที่ที่ข้อมูลจริงใช้งานอยู่
จากนั้นจึงเป็นการปรับแต่งค่าต่างๆ โดยสังเขป บน Linux คุณสามารถอ่านค่าปัจจุบันได้ดังนี้:
cat /sys/module/zfs/parameters/zfs_scrub_min_time_ms
cat /sys/module/zfs/parameters/zfs_vdev_scrub_max_activeFreeBSD เปิดเผยพารามิเตอร์เดียวกันผ่าน sysctl ดังนั้นให้ค้นหาค่าของคุณด้วย sysctl -a | grep scrub การเพิ่มค่าเหล่านี้จะทำให้การทำ scrub เสร็จเร็วขึ้นแต่จะทำให้แอปพลิเคชันของคุณทำงานช้าลง การลดค่าจะให้ผลตรงกันข้าม บน pool ที่มีอุปกรณ์เพียงหนึ่งหรือสองตัว ไม่มีค่าใดที่จะให้ผลลัพธ์ที่ดีทั้งสองด้าน เพราะมีคิวเพียงคิวเดียวให้แบ่งใช้งาน การปรับแต่งค่าเพียงอย่างเดียวมักไม่สามารถแก้ไขปัญหาด้านการออกแบบได้ หากการทำ scrub รายเดือนส่งผลกระทบต่อระบบ ความเป็นจริงคือ pool ของคุณอาจเต็มเกินไปหรืออุปกรณ์ทำงานช้าเกินไป และการปรับแต่งค่าเป็นเพียงการย้ายปัญหาไปไว้ที่อื่นเท่านั้น
เวลาที่ใช้ในการ scrub คือตัวอย่างล่วงหน้าของระยะเวลา resilver
กระบวนการ resilver ทำงานในลักษณะเดียวกับ scrub คือการอ่านบล็อกข้อมูลที่ถูกจัดสรรไว้ ตรวจสอบความถูกต้อง และเขียนข้อมูลที่ขาดหายไปยังอุปกรณ์ที่นำมาเปลี่ยนใหม่ ดังนั้นเวลาที่ใช้ในการ scrub จึงเป็นตัวบ่งชี้ที่ตรงไปตรงมาที่สุดว่าการสร้างข้อมูลใหม่ (rebuild) จะใช้เวลานานเท่าใด และ pool จะต้องทำงานในสภาวะที่มี redundancy ลดลงนานแค่ไหนในระหว่างนั้น
ZFS จัดลำดับความสำคัญของงาน resilver ให้มีความต่อเนื่องมากกว่างาน scrub ดังนั้นการ rebuild มักจะเสร็จสิ้นเร็วกว่าการ scrub ใน pool เดียวกัน ให้ถือว่าเวลาที่ใช้ในการ scrub เป็นค่าประมาณการขั้นสูงที่ปลอดภัย หากการ scrub ใช้เวลา 9 ชั่วโมง ให้วางแผนเผื่อเวลาสำหรับการ rebuild ในระดับเดียวกัน และต้องเข้าใจว่าหากเกิดความล้มเหลวของอุปกรณ์ตัวที่สองภายในช่วงเวลานี้ ข้อมูลใน pool จะสูญหาย นี่คือเหตุผลเชิงปฏิบัติที่ควรเลือกใช้ mirrored pairs แทนการใช้ raidz group ขนาดใหญ่ เนื่องจาก raidz ซึ่งเป็นรูปแบบการจัดเก็บข้อมูลแบบ parity ที่ ZFS ใช้แทน RAID 5 นั้น จะต้องทำการ rebuild โดยการอ่านข้อมูลจากอุปกรณ์ที่เหลืออยู่ทั้งหมด
ใน pool ที่มีอุปกรณ์เพียงตัวเดียว จะไม่มีกระบวนการ resilver เกิดขึ้น หากอุปกรณ์นั้นเสีย pool ก็จะใช้งานไม่ได้ทันที ระยะเวลาในการกู้คืนของคุณคือระยะเวลาในการ restore ข้อมูล ดังนั้นให้วัดเวลาจากการ restore แทน การ restore ที่คุณไม่เคยทดสอบจริง ไม่ถือว่าเป็นแผนการกู้คืนข้อมูล
สิ่งที่เปลี่ยนไปเมื่อคุณเช่าดิสก์
บน VPS อุปกรณ์บล็อก (block device) จะเป็นแบบเสมือน ตัวไฮเปอร์ไวเซอร์จะนำเสนอโวลุ่มให้ โดยเบื้องหลังอาจเป็น NVMe ในเครื่อง หรือเป็นโวลุ่มเครือข่ายที่มีการทำสำเนาและมี parity ในตัว ซึ่งส่งผลสองประการต่อการทำ scrub
ประการแรก ความซ้ำซ้อนของแพลตฟอร์มนั้นมองไม่เห็นสำหรับ ZFS และ ZFS ไม่สามารถใช้งานมันได้ หากแพลตฟอร์มซ่อมแซมข้อผิดพลาดของสื่อบันทึกข้อมูลที่อยู่ต่ำกว่าระดับของคุณ ZFS จะไม่ทราบถึงปัญหานั้นเลย แต่หากแพลตฟอร์มส่งบล็อกข้อมูลที่ผิดพลาดขึ้นมา ZFS จะตรวจพบแต่ไม่สามารถแก้ไขได้ เนื่องจากสำเนาที่ถูกต้องนั้นอยู่อีกฝั่งหนึ่งของขอบเขตดังกล่าว
ประการที่สอง โดยปกติคุณจะไม่สามารถอ่านข้อมูล SMART (self-monitoring, analysis and reporting technology) ของอุปกรณ์ที่อยู่ใต้ดิสก์เสมือนได้ ดังนั้นการแจ้งเตือนล่วงหน้าที่ การตรวจสอบสุขภาพดิสก์บน VPS ต้องอาศัยนั้นอาจไม่มีให้ใช้งานเลย ตัวนับ CKSUM จากการทำ scrub ของคุณจึงกลายเป็นสัญญาณหลักที่คุณมี
หากคุณต้องการให้ ZFS ทำการซ่อมแซมแทนที่จะแค่รายงาน พูล (pool) จำเป็นต้องมีอุปกรณ์มากกว่าหนึ่งตัวภายในอินสแตนซ์เดียวกัน ซึ่งเป็นการตัดสินใจเชิงวางแผนไม่ใช่การปรับแต่ง การเลือก storage VPS แทน VPS ปกติ จะทำให้คุณได้ความจุเพิ่มขึ้น แต่การจะได้อุปกรณ์ที่แยกจากกันจริงหรือไม่นั้นขึ้นอยู่กับแพ็กเกจ ให้รัน lsblk เพื่อตรวจสอบให้แน่ใจก่อนที่จะสร้าง mirror บนสิ่งที่กลายเป็นเพียงสองส่วนของโวลุ่มเดียวกัน เราให้เช่าเซิร์ฟเวอร์ Linux และ FreeBSD ไม่ใช่อุปกรณ์ ZFS แบบจัดการสำเร็จรูป ดังนั้นกำหนดการ scrub และการสำรองข้อมูลจึงเป็นหน้าที่ของคุณ นี่คือข้อแลกเปลี่ยนที่คุณได้รับ: การควบคุมพูลอย่างเต็มรูปแบบ และการรับผิดชอบต่อการบำรุงรักษาด้วยตัวคุณเองทั้งหมด
FAQ
ฉันควรทำ scrub บน ZFS pool ใน VPS บ่อยแค่ไหน?
การทำรายเดือนเหมาะสมกับ pool ขนาดเล็กส่วนใหญ่ และสอดคล้องกับสิ่งที่แพ็กเกจตั้งค่าไว้ให้แล้ว เช่น งาน cron job ในวันอาทิตย์ที่สองของเดือนบน Debian และ Ubuntu หรือเกณฑ์มาตรฐาน 35 วันในระบบ periodic ของ FreeBSD การทำรายสัปดาห์จะสมเหตุสมผลก็ต่อเมื่อคุณได้ทดสอบเวลาที่ใช้ในการ scrub แล้วพบว่ามันเสร็จสิ้นอย่างรวดเร็วบนเครื่องที่ไม่ได้ใช้งานหนัก สำหรับ pool ที่มีการใช้งานสูงและมีอุปกรณ์เพียงหนึ่งหรือสองตัว การทำ scrub รายสัปดาห์จะแย่งทรัพยากร I/O ของแอปพลิเคชันไปทุกสัปดาห์ โดยแลกกับการแจ้งเตือนล่วงหน้าเพียงไม่กี่สัปดาห์เท่านั้น
การทำ scrub บน ZFS pool ที่มีดิสก์ลูกเดียวไร้ประโยชน์หรือไม่?
ไม่ไร้ประโยชน์ ตราบใดที่คุณเข้าใจชัดเจนว่ามันช่วยอะไรได้บ้าง ในกรณีที่ไม่มีความซ้ำซ้อน (redundancy) การ scrub จะตรวจพบความเสียหายแต่ไม่สามารถซ่อมแซมได้ ยกเว้นในส่วนของ metadata ซึ่ง ZFS จะเก็บสำเนาสำรองไว้ให้โดยค่าเริ่มต้น สิ่งที่คุณจะได้รับคือรายการชื่อไฟล์ที่เสียหายใน zpool status -v ซึ่งเร็วพอที่คุณจะกู้คืนไฟล์เหล่านั้นจากแหล่งอื่นที่ยังมีสำเนาที่สมบูรณ์อยู่ สิ่งที่ควรทำคือการปรับปรุงระบบสำรองข้อมูลให้ดีขึ้น เพราะการ scrub จะระบุให้คุณทราบอย่างชัดเจนว่าต้องกู้คืนไฟล์ใด
ฉันสามารถหยุดพักการ scrub ของ ZFS แล้วกลับมาทำต่อภายหลังได้หรือไม่?
ได้ คุณสามารถใช้ zpool scrub -p tank เพื่อหยุดพักการทำงานชั่วคราว โดยสถานะการหยุดพักและความคืบหน้าจะถูกบันทึกลงดิสก์เป็นระยะ ดังนั้นการ scrub จะยังคงอยู่ในสถานะหยุดพักแม้จะทำการ export หรือ reboot เครื่องไปแล้ว ให้รัน zpool scrub tank อีกครั้งเพื่อดำเนินการต่อจากจุดตรวจสอบล่าสุด ห้ามใช้ zpool scrub -s tank ในกรณีนี้ เพราะ -s จะเป็นการยกเลิกการ scrub และการเริ่มครั้งถัดไปจะเริ่มต้นใหม่ตั้งแต่ต้น
ทำไมการ scrub ของ ZFS ถึงช้า และฉันจะเร่งความเร็วได้หรือไม่?
เวลาที่ใช้ในการ scrub ขึ้นอยู่กับปริมาณข้อมูลที่ถูกจัดสรรและการกระจัดกระจายของข้อมูล (fragmentation) ไม่ใช่ความจุของดิสก์ Pool ที่มีข้อมูลเกิน 90% จะทำงานช้าลงเนื่องจาก metaslabs ที่เหลือพื้นที่น้อยกว่า 4% จะบีบให้ตัวจัดสรรข้อมูลเปลี่ยนจากการเลือกตำแหน่งว่างแรกที่พบ (first-fit) ไปเป็นการเลือกตำแหน่งที่เหมาะสมที่สุด (best-fit) และการกระจัดกระจายที่ตามมาจะทำให้การ scrub กลายเป็นการอ่านข้อมูลขนาดเล็กจำนวนมาก การเพิ่มพื้นที่ว่างมักช่วยได้มากกว่าการปรับจูนค่าใดๆ คุณสามารถเพิ่มค่า zfs_scrub_min_time_ms หรือ zfs_vdev_scrub_max_active เพื่อให้การ scrub ได้รับส่วนแบ่งของคิวมากขึ้น แต่สำหรับ pool ที่มีอุปกรณ์เพียงหนึ่งหรือสองตัว ส่วนแบ่งนั้นจะถูกดึงมาจากทรัพยากรของแอปพลิเคชันของคุณโดยตรง