อ่านประมาณ 9 นาที
ระดับสูง
หมวด: คลาวด์
อ้างอิง: Cloudflare Blog — How we saved 100 terabytes of memory by optimizing 1.1.1.1's DNS cache
เมื่อระบบมีรายการแคชกว่า 250,000 ล้านรายการ การเปลืองหน่วยความจำเพียงหนึ่งไบต์ต่อรายการเท่ากับสูญเปล่าไปกว่า 250 กิกะไบต์ บทความนี้ถอดวิธีลดขนาดต่อรายการลง 56% ทีละขั้น พร้อมบทเรียนเรื่องการวัดผลที่ทีมไทยนำไปใช้กับระบบของตัวเองได้
โจทย์: หนึ่งไบต์ที่คูณด้วย 250,000 ล้าน
แพลตฟอร์ม DNS ที่บทความพูดถึงดูแลรายการแคชรวมกันมากกว่า 250,000 ล้านรายการทั่วทั้งฟลีต ที่ขนาดนี้ตัวเลขเล็ก ๆ กลายเป็นเรื่องใหญ่ทันที การเปลืองหน่วยความจำเพียงหนึ่งไบต์ต่อรายการเท่ากับใช้หน่วยความจำเพิ่มขึ้นกว่า 250 กิกะไบต์ทั้งระบบ ทีมจึงตั้งโจทย์ว่าจะลดขนาดต่อรายการลงอย่างไรโดยไม่ทำให้ประสิทธิภาพแย่ลง
โครงสร้างเดิมประกอบด้วยคีย์ที่เก็บชื่อโดเมน ชนิดของคำถาม แฟล็กการยืนยันตัวตน และแท็ก ส่วนตัวรายการเก็บเวลาประทับ อายุของข้อมูล ตัวนับการถูกเรียกใช้ รายการเรกคอร์ดสามชุดแยกกัน และข้อมูลข้อผิดพลาด ปัญหาคือโครงสร้างนี้ใช้คอลเลกชันมาตรฐานของภาษาที่ออกแบบมาสำหรับข้อมูลที่แก้ไขได้ ทั้งที่ข้อมูลในแคชไม่เคยถูกแก้หลังบันทึกแล้ว
ห้าการเปลี่ยนแปลงที่ทำทีละขั้น
ขั้นแรกคือเปลี่ยนจากรายการแบบขยายได้เป็นรายการขนาดคงที่ เพราะคำตอบ DNS ไม่เคยเปลี่ยนหลังถูกแคช โครงสร้างแบบขยายได้จึงเปลืองพื้นที่ไปกับฟิลด์ความจุที่ไม่มีวันได้ใช้ บวกกับการจองหน่วยความจำเผื่อไว้เกินจำเป็น เฉพาะขั้นนี้ประหยัดได้ราว 15 เทระไบต์
ขั้นที่สองคือรวมรายการเรกคอร์ดสามชุดให้เหลือชุดเดียวที่ต่อเนื่องกัน แล้วใช้ตัวเลขบอกตำแหน่งขนาด 2 ไบต์สองตัวเป็นเส้นแบ่งส่วน แทนที่จะเก็บคู่ตัวชี้กับความยาวสามชุด ผลคือลดข้อมูลกำกับจาก 48 ไบต์เหลือ 4 ไบต์ ขั้นที่สามคือเลิกเก็บชื่อเจ้าของเรกคอร์ดซ้ำ เพราะส่วนใหญ่ตรงกับชื่อโดเมนที่ถามอยู่แล้ว จึงอนุมานจากคีย์ตอนอ่านได้ และเก็บเฉพาะกรณีที่ต่างออกไป
ภาพประกอบบทความหมวดคลาวด์
ขั้นที่ได้ผลที่สุดและบทเรียนเรื่องการแลกได้แลกเสีย
ขั้นที่สี่คือแก้ปัญหาที่ชนิดข้อมูลแบบเลือกได้หลายแบบถูกจองขนาดตามตัวที่ใหญ่ที่สุดเสมอ ทำให้เรกคอร์ดชนิดที่ใช้บ่อยที่สุดต้องแบกพื้นที่ว่างไปด้วยกว่า 120 ไบต์ วิธีแก้แรกคือย้ายตัวแปรใหญ่ ๆ ไปไว้บนฮีปแยก แต่กลับเจอผลข้างเคียงคือภาระของตัวจัดสรรหน่วยความจำเพิ่มขึ้นและข้อมูลกระจัดกระจายจนซีพียูอ่านช้าลง
ขั้นที่ห้าซึ่งให้ผลดีที่สุดคือเก็บข้อมูลเรกคอร์ดเป็นไบต์ดิบตามรูปแบบที่ใช้ส่งบนสายจริง รวมไว้ในบัฟเฟอร์เดียวที่ต่อเนื่องกันโดยมีตัวเลขบอกความยาวนำหน้าแต่ละชิ้น วิธีนี้ตัดทั้งภาระของชนิดข้อมูลแบบเลือกได้และการจองหน่วยความจำแยกก้อนออกไปพร้อมกัน อีกทั้งยังทำให้ข้อมูลอยู่ติดกันจนซีพียูอ่านได้เร็วขึ้น โดยเรกคอร์ดที่ต้องบีบอัดชื่อโดเมนยังคงถูกแปลงตอนอ่าน ส่วนที่เหลือคัดลอกไปใส่คำตอบได้ตรง ๆ
ผลลัพธ์ที่วัดได้จริง
ขนาดต่อรายการลดจาก 953 ไบต์เหลือ 420 ไบต์ คิดเป็นการลดลง 56% ส่วนการจองหน่วยความจำต่อรายการลดจาก 1.1 กิโลไบต์เหลือ 461 ไบต์ หรือลดลง 58% เมื่อวัดในระบบจริง หน่วยความจำที่ใช้อยู่จริงของอินสแตนซ์ที่เปอร์เซ็นไทล์ 99 ลดจาก 9.3 กิกะไบต์เหลือ 5.3 กิกะไบต์ และรวมทั้งฟลีตประหยัดได้ราว 100 เทระไบต์
สิ่งที่ทำให้กรณีนี้น่าสนใจเป็นพิเศษคือไม่ได้แลกความเร็วเพื่อพื้นที่ แต่ได้ทั้งสองอย่าง อัตราการบันทึกลงแคชเพิ่มขึ้น 43% จาก 625,000 เป็น 893,000 รายการต่อวินาที และความหน่วงในการค้นหาลดลง 19% จาก 828 เหลือ 670 นาโนวินาที
ภาพประกอบบทความหมวดคลาวด์
บทเรียนที่ทีมไทยนำไปใช้ได้
บทเรียนข้อแรกคือต้องวัดก่อนแก้ ทีมสร้างตัวห่อหุ้มตัวจัดสรรหน่วยความจำขึ้นมาเองเพื่อนับการจองต่อรายการควบคู่กับตัวชี้วัดประสิทธิภาพ ซึ่งเป็นสิ่งที่ทำให้รู้ว่าการเปลี่ยนแต่ละขั้นได้ผลจริงหรือไม่ ข้อที่สองคือผลจากการทดสอบในห้องกับผลในระบบจริงต่างกันเสมอ ตัวเลข 56% จากการวัดต่อรายการกลายเป็น 42-43% เมื่อวัดหน่วยความจำจริงของเครื่อง เพราะมีภาระอื่นที่การทดสอบสังเคราะห์ไม่ครอบคลุม
ข้อที่สามคือปรับทีละขั้นดีกว่ารื้อใหญ่ครั้งเดียว การแบ่งเป็นห้าขั้นทำให้วัดผลระหว่างทางได้และย้อนกลับได้เมื่อขั้นใดให้ผลแย่ลง ซึ่งเกิดขึ้นจริงในขั้นที่สี่ และข้อสุดท้ายคือปรับให้เหมาะกับกรณีที่พบบ่อยที่สุด การเลือกปรับให้เข้ากับเรกคอร์ด 80% ที่คัดลอกตรงได้ ให้ผลตอบแทนมากกว่าการพยายามทำให้ทุกกรณีดีเท่ากัน สำหรับทีมไทยที่ดูแลระบบซึ่งเก็บข้อมูลจำนวนมากในหน่วยความจำ เช่น แคชของ API หรือคิวงาน หลักคิดชุดนี้ใช้ได้ตรง ๆ แม้จะไม่ได้ทำงานที่สเกลระดับเดียวกัน
สรุปสาระสำคัญ โจทย์: หนึ่งไบต์ที่คูณด้วย 250,000 ล้าน ห้าการเปลี่ยนแปลงที่ทำทีละขั้น ขั้นที่ได้ผลที่สุดและบทเรียนเรื่องการแลกได้แลกเสีย
แหล่งอ้างอิง เรียบเรียงจาก Cloudflare Blog — How we saved 100 terabytes of memory by optimizing 1.1.1.1's DNS cache —
อ่านบทความต้นฉบับ ภาพปก: Cloudflare Blog · ลิขสิทธิ์ภาพเป็นของเจ้าของต้นฉบับ ใช้ประกอบการรายงานพร้อมอ้างอิงแหล่งที่มา
มีคำถามเพิ่มเติมเกี่ยวกับบทความนี้? เขียนหาเราได้ที่
info@smart-cyber-tech.com
บริการที่เกี่ยวข้องจากทีมงาน Smart Cyber Tech
แบ่งปันบทความนี้:
LINE
Facebook
X
คัดลอกลิงก์
ปรึกษาทีมของเรา