การลดลงของประสิทธิภาพเกิดขึ้นเมื่อzpoolของคุณเต็มหรือแยกส่วนมาก เหตุผลนี้เป็นกลไกของการค้นพบบล็อกฟรีที่ใช้กับ ZFS ตรงข้ามกับระบบไฟล์อื่น ๆ เช่น NTFS หรือ ext3 ไม่มีบล็อกบิตแมปที่แสดงว่ามีบล็อกใดบ้างและว่าง แต่ ZFS จะแบ่ง zvol ของคุณออกเป็นพื้นที่ขนาดใหญ่กว่าปกติที่เรียกว่า "metaslabs" และเก็บ AVL-trees 1ของข้อมูลบล็อกฟรี (แผนที่พื้นที่) ในแต่ละ metaslab แผนผัง AVL ที่สมดุลช่วยให้สามารถค้นหาบล็อกที่เหมาะสมกับขนาดของคำขอได้อย่างมีประสิทธิภาพ
ในขณะที่กลไกนี้ได้รับเลือกด้วยเหตุผลของสเกล แต่น่าเสียดายที่มันกลายเป็นความเจ็บปวดที่สำคัญเมื่อมีการกระจายตัวของระดับสูงและ / หรือการใช้พื้นที่เกิดขึ้น ทันทีที่เมตาแท็บทั้งหมดมีข้อมูลจำนวนมากคุณจะได้รับพื้นที่เล็ก ๆ จำนวนมากของบล็อกฟรีซึ่งต่างจากพื้นที่ขนาดใหญ่จำนวนเล็กน้อยเมื่อสระว่างเปล่า หาก ZFS ต้องการจัดสรรพื้นที่ว่าง 2 MB มันจะเริ่มอ่านและประเมินแผนที่อวกาศของ metaslabs ทั้งหมดเพื่อหาบล็อกที่เหมาะสมหรือหาวิธีแบ่ง 2 MB เป็นบล็อกขนาดเล็ก แน่นอนว่าต้องใช้เวลาพอสมควร อะไรคือสิ่งที่เลวร้ายก็คือความจริงที่ว่ามันจะเสียค่าใช้จ่ายเป็นจำนวนมากทั้งของการดำเนินงาน I / O เป็น ZFS แน่นอนจะอ่านทุกพื้นที่แผนที่ปิดดิสก์ทางกายภาพ สำหรับการเขียนใด ๆของคุณ
การลดลงของประสิทธิภาพอาจมีนัยสำคัญ หากคุณนึกภาพสวย ๆ ลองดูที่โพสต์ในบล็อกที่ Delphixซึ่งมีตัวเลขบางตัวที่ถูกนำออกไป ฉันขโมยกราฟอย่างไร้ยางอาย - ดูที่เส้นสีฟ้า, สีแดง, สีเหลืองและสีเขียวในกราฟนี้ซึ่งเป็น (ตามลำดับ) ซึ่งแสดงถึงกลุ่มที่ 10%, 50%, 75% และ 93% ของความสามารถในการเขียนปริมาณงาน KB / s ขณะที่มีการแยกส่วนเมื่อเวลาผ่านไป:
การแก้ไขอย่างรวดเร็วและสกปรกนี้เป็นวิธีการแก้จุดบกพร่องแบบดั้งเดิมของmetaslab (เพียงแค่echo metaslab_debug/W1 | mdb -kw
เรียกใช้ ณ เวลาทำงานเพื่อเปลี่ยนการตั้งค่าทันที) ในกรณีนี้แผนที่อวกาศทั้งหมดจะถูกเก็บไว้ใน OS RAM โดยลบข้อกำหนดสำหรับ I / O ที่มากเกินไปและแพงในการดำเนินการเขียนแต่ละครั้ง ในท้ายที่สุดนี้ยังหมายถึงคุณต้องการหน่วยความจำมากขึ้นโดยเฉพาะอย่างยิ่งสำหรับพูลขนาดใหญ่ดังนั้นมันจึงเป็นแรมสำหรับจัดเก็บม้าค้าขาย พูล 10 TB ของคุณอาจจะต้องเสียค่าใช้จ่าย 2-4 GB ของหน่วยความจำ2แต่คุณจะสามารถใช้งานได้ถึง 95% ของการใช้งานโดยไม่ต้องยุ่งยากมาก
1มันซับซ้อนกว่านี้นิดหน่อยถ้าคุณสนใจลองดูที่โพสต์ของ Bonwick บนแผนที่อวกาศเพื่อดูรายละเอียด
2ถ้าคุณต้องการวิธีการคำนวณขีด จำกัด สูงสุดสำหรับหน่วยความจำใช้zdb -mm <pool>
เพื่อดึงข้อมูลจำนวนที่segments
ใช้อยู่ในปัจจุบันในแต่ละ metaslab หารด้วยสองเพื่อจำลองสถานการณ์สถานการณ์ที่เลวร้ายที่สุด (แต่ละเซ็กเมนต์ว่างจะตามด้วยฟรีหนึ่ง ) คูณด้วยขนาดเรคคอร์ดสำหรับโหนด AVL (ตัวชี้หน่วยความจำสองตัวและค่าหนึ่งชุดเนื่องจากลักษณะของ zfs 128 บิตและการกำหนดแอดเดรส 64- บิตจะรวมกันได้ถึง 32 ไบต์แม้ว่าคนทั่วไปจะคิดว่า 64 ไบต์สำหรับบางคน เหตุผล).
zdb -mm tank | awk '/segments/ {s+=$2}END {s*=32/2; printf("Space map size sum = %d\n",s)}'
การอ้างอิง: โครงร่างพื้นฐานอยู่ในการโพสต์นี้โดย Markus Kovero ในรายชื่อผู้รับจดหมาย zfs-discussแม้ว่าฉันเชื่อว่าเขาทำผิดพลาดบางอย่างในการคำนวณของเขาซึ่งฉันหวังว่าจะได้รับการแก้ไขในเหมือง
volume
ที่ 8.5T และไม่เคยคิดถึงมันอีกเลย ถูกต้องไหม