9 คะแนน โดย GN⁺ 2024-11-01 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • Robinhood คือบริการโหลดบาลานซ์ภายในของ Dropbox ที่เริ่มใช้งานในปี 2020
  • บริการนี้ทำหน้าที่กำหนดเส้นทางทราฟฟิกภายในระหว่างเซิร์ฟเวอร์เพื่อกระจายโหลดของบริการอย่างสมดุล
  • ก่อนมี Robinhood บริการส่วนใหญ่ของ Dropbox ประสบปัญหาจากการกระจายโหลดระหว่างแบ็กเอนด์ที่ไม่สมดุล
  • ความแตกต่างของฮาร์ดแวร์และข้อจำกัดของอัลกอริทึมโหลดบาลานซ์แบบเดิมทำให้เกิดปัญหาด้านความน่าเชื่อถือจากอินสแตนซ์ที่โอเวอร์โหลด
  • เพื่อแก้ปัญหานี้ จำเป็นต้องโปรวิชัน service fleet เกินความต้องการ ซึ่งนำไปสู่ต้นทุนฮาร์ดแวร์ที่สูงขึ้น

ความสามารถใหม่ของ Robinhood

  • มีการนำคอนโทรลเลอร์ PID (Proportional-Integral-Derivative) มาใช้ ทำให้จัดการความไม่สมดุลของโหลดได้รวดเร็วและมีประสิทธิภาพมากขึ้น
  • สิ่งนี้นำไปสู่การปรับปรุงความน่าเชื่อถือของโครงสร้างพื้นฐานและลดต้นทุนฮาร์ดแวร์ได้อย่างมาก
  • เมื่อเวิร์กโหลด AI ที่ขับเคลื่อนความสามารถอัจฉริยะสมัยใหม่เพิ่มขึ้น การจัดการอุปสงค์ต่อทรัพยากร GPU อย่างมีประสิทธิภาพจึงสำคัญกว่าที่เคย

ความท้าทายของการทำโหลดบาลานซ์ที่ Dropbox

  • ระบบ service discovery ของ Dropbox สามารถสเกลไปยังโฮสต์หลายแสนเครื่องที่กระจายอยู่ในดาต้าเซ็นเตอร์ทั่วโลก
  • บริการบางอย่างของ Dropbox มีไคลเอนต์หลายล้านราย แต่ไม่สามารถอนุญาตให้ไคลเอนต์แต่ละรายเชื่อมต่อกับทุกเซิร์ฟเวอร์อินสแตนซ์ได้
    • เพราะจะสร้างแรงกดดันต่อหน่วยความจำของเซิร์ฟเวอร์มากเกินไป และเมื่อเซิร์ฟเวอร์รีสตาร์ตอาจเกิดโอเวอร์โหลดจาก TLS handshake ได้
  • ดังนั้นจึงใช้ระบบ service discovery เพื่อมอบชุดย่อยของเซิร์ฟเวอร์ที่ไคลเอนต์ควรเชื่อมต่อให้กับไคลเอนต์แต่ละราย
  • กลยุทธ์โหลดบาลานซ์ที่ดีที่สุดที่ไคลเอนต์สามารถใช้ได้คือทำ round-robin กับรายการที่อยู่จากระบบ service discovery
    • แต่ด้วยวิธีนี้ โหลดของแต่ละเซิร์ฟเวอร์อินสแตนซ์อาจไม่สมดุลกันมาก
    • การเพิ่มขนาดของชุดย่อยเป็นวิธีบรรเทาที่ทำได้ง่าย แต่ไม่ได้ขจัดความไม่สมดุลทั้งหมด และเพียงเพิ่มพารามิเตอร์อีกตัวให้เจ้าของบริการต้องดูแล
  • ปัญหาที่ลึกกว่านั้นคือ ถึงแม้จะส่งคำขอไปยังแต่ละเซิร์ฟเวอร์ในจำนวนเท่ากัน ฮาร์ดแวร์พื้นฐานของแต่ละเซิร์ฟเวอร์ก็อาจแตกต่างกัน
    • กล่าวคือ คำขอเดียวกันอาจใช้ทรัพยากรไม่เท่ากันบนฮาร์ดแวร์แต่ละคลาส
  • ประเด็นสำคัญคือไคลเอนต์มองไม่เห็นโหลดของเซิร์ฟเวอร์
  • ในอดีต Dropbox เคยพยายามแก้ปัญหานี้โดยให้เซิร์ฟเวอร์แนบข้อมูลโหลดไว้ใน response header
    • จากนั้นไคลเอนต์สามารถทำโหลดบาลานซ์เองได้โดยเลือกเอนด์พอยต์ที่มีโหลดต่ำที่สุดจากชุดย่อยของที่อยู่
    • แม้ผลลัพธ์จะดูมีแนวโน้มที่ดี แต่ก็ยังมีข้อเสียบางประการ
      • เนื่องจากทั้งฝั่งเซิร์ฟเวอร์และไคลเอนต์ต้องแก้โค้ดเพื่อรองรับ load header แบบพิเศษ จึงยากต่อการนำไปใช้ทั่วทั้งระบบ
      • ผลลัพธ์ดี แต่ยังดีไม่พอ

การตัดสินใจสร้าง Robinhood

  • ในปี 2019 มีการตัดสินใจอย่างเป็นทางการให้สร้าง Robinhood
  • บริการใหม่นี้ถูกสร้างขึ้นบนระบบ service discovery ภายในที่มีอยู่เดิม โดยรวบรวมข้อมูลโหลดจากเซิร์ฟเวอร์และแนบเข้ากับข้อมูลการกำหนดเส้นทาง
  • Robinhood ใช้ Endpoint Discovery Service ของ Envoy เพื่อผสานข้อมูลโหลดเข้ากับน้ำหนักของเอนด์พอยต์ ทำให้ไคลเอนต์สามารถทำ weighted round-robin ได้
  • ชุมชน gRPC กำลังรับเอาโปรโตคอล Envoy xDS มาใช้ ทำให้ Robinhood ใช้งานร่วมได้ทั้งกับ Envoy และไคลเอนต์ gRPC
  • ในเวลานั้นไม่มีโซลูชันโหลดบาลานซ์ที่มีอยู่ซึ่งตอบโจทย์ความต้องการของ Dropbox ได้ จึงตัดสินใจสร้างบริการใหม่ขึ้นมา

ผลลัพธ์ของ Robinhood

  • หลังใช้งานในโปรดักชันมาหลายปี พบผลลัพธ์ที่น่าพอใจ
  • สามารถลดขนาด fleet ของบริการขนาดใหญ่บางส่วนลงได้ 25% ส่งผลให้ประหยัดต้นทุนฮาร์ดแวร์ต่อปีได้อย่างมาก
  • ความน่าเชื่อถือก็ดีขึ้นด้วย เพราะมีโปรเซสที่ถูกใช้งานหนักเกินไปน้อยลง

สถาปัตยกรรมของ Robinhood

  • ในแต่ละดาต้าเซ็นเตอร์จะมีการดีพลอยอินสแตนซ์ของ Robinhood ซึ่งประกอบด้วย 3 ส่วน ได้แก่ บริการโหลดบาลานซ์ พร็อกซี และฐานข้อมูลเส้นทาง

บริการโหลดบาลานซ์ (LBS)

  • เป็นแกนหลักของ Robinhood
  • มีหน้าที่รวบรวมข้อมูลโหลดและสร้างข้อมูลการกำหนดเส้นทางที่มีน้ำหนักของเอนด์พอยต์
  • เนื่องจากมีหลายอินสแตนซ์อัปเดตข้อมูลการกำหนดเส้นทางของบริการพร้อมกัน จึงใช้ shard manager ภายในเพื่อกำหนด worker หลักให้แต่ละบริการ
  • เพราะแต่ละบริการเป็นอิสระจากกัน จึงสามารถแบ่ง LBS ตามบริการและสเกลแนวนอนได้

พร็อกซี

  • ทำหน้าที่ส่งข้อมูลโหลดของบริการไปยังพาร์ทิชัน LBS ที่เกี่ยวข้องภายในดาต้าเซ็นเตอร์
  • การใช้พร็อกซียังช่วยลดจำนวนการเชื่อมต่อโดยตรงเข้าสู่โปรเซส LBS
    • หากไม่มีพร็อกซี ทุกโปรเซส LBS จะต้องเชื่อมต่อกับทุกโหนดในโครงสร้างพื้นฐาน
    • แต่เมื่อให้โปรเซส LBS เชื่อมต่อเฉพาะกับพร็อกซี แรงกดดันต่อหน่วยความจำของ LBS ก็ลดลงอย่างมาก
  • พร็อกซีเชื่อมต่อเฉพาะกับโหนดภายในดาต้าเซ็นเตอร์เดียวกัน จึงสามารถสเกลแนวนอนได้
  • แพตเทิร์นนี้ถูกใช้ในหลายส่วนของโครงสร้างพื้นฐานเพื่อป้องกันไม่ให้บริการต้องรับการเชื่อมต่อ TLS มากเกินไป

ฐานข้อมูลเส้นทาง

  • เป็นฐานข้อมูลบน ZooKeeper/etcd สำหรับเก็บข้อมูลการกำหนดเส้นทางของบริการ เช่น ชื่อโฮสต์ ที่อยู่ IP และค่าน้ำหนักที่ LBS สร้างขึ้น
  • ZooKeeper และ etcd สามารถแจ้งการเปลี่ยนแปลงของโหนด/คีย์ให้กับ watcher ทั้งหมดได้แบบเรียลไทม์ และเหมาะมากกับกรณีใช้งาน service discovery ที่เน้นการอ่านของ Dropbox
  • ความสอดคล้องแบบ eventual consistency ที่ ZooKeeper/etcd รับประกันนั้นเพียงพอสำหรับ service discovery เช่นกัน

เจาะลึกบริการโหลดบาลานซ์

  • เป้าหมายของการทำโหลดบาลานซ์คือทำให้การใช้งานของทุกโหนดเท่ากับค่าเฉลี่ยของการใช้งาน
  • ใช้คอนโทรลเลอร์ PID เพื่อรักษาการใช้งานของแต่ละโหนดให้ใกล้เคียงกับค่าเฉลี่ยมากที่สุด
  • LBS จะสร้างคอนโทรลเลอร์ PID สำหรับแต่ละโหนด และใช้ค่าเฉลี่ยของการใช้งานเป็น setpoint
  • LBS ใช้ผลลัพธ์ของคอนโทรลเลอร์ PID เป็น delta สำหรับค่าน้ำหนักของเอนด์พอยต์ และทำ normalization ของน้ำหนักระหว่างทุกเอนด์พอยต์ของบริการ
  • แม้โหนดใหม่จะต้องใช้การปรับหลายครั้งกว่าจะเข้าใกล้ค่าเฉลี่ยของการใช้งาน แต่คอนโทรลเลอร์ PID ก็มีประสิทธิภาพมากในการทำโหลดบาลานซ์

สถานการณ์การทำงานของ LBS

  • LBS ถูกออกแบบมาให้จัดการกับสถานการณ์หลากหลายที่อาจส่งผลต่อการทำโหลดบาลานซ์ ตั้งแต่การรีสตาร์ตโหนดไปจนถึงการขาดหายของรายงานโหลด
  • เพื่อคงประสิทธิภาพที่เหมาะสม LBS จึงมีการใช้กลยุทธ์หลายอย่างเพื่อจัดการกรณียกเว้นเหล่านี้

การเริ่มต้น LBS

  • LBS เก็บข้อมูลโหลดและสถานะของคอนโทรลเลอร์ PID ไว้ในหน่วยความจำ
  • ระหว่างการรีสตาร์ต LBS จะยังไม่เริ่มอัปเดตค่าน้ำหนักในทันที แต่จะรอสักครู่จนกว่ารายงานโหลดจะเข้ามา
  • สำหรับค่าน้ำหนักของคอนโทรลเลอร์ PID นั้น LBS จะอ่านค่าน้ำหนักของเอนด์พอยต์จากฐานข้อมูลเส้นทางเพื่อกู้คืนกลับมา

โหนด Cold Start

  • เนื่องจากมีโหนดใหม่เข้าร่วมใน service fleet อยู่บ่อยครั้ง การป้องกันปัญหา Thundering Herd จึงสำคัญ
  • เพราะการใช้งานเริ่มต้นของโหนดใหม่มักเป็น 0 LBS จึงตั้งค่าน้ำหนักของโหนดใหม่ไว้ที่น้ำหนักเอนด์พอยต์ต่ำ และปล่อยให้คอนโทรลเลอร์ PID ค่อยๆ ดึงโหนดนั้นขึ้นสู่ค่าเฉลี่ยของการใช้งาน

รายงานโหลดที่หายไป

  • ในสภาพแวดล้อมของระบบกระจาย ความขัดข้องเป็นเรื่องปกติ
  • จากความแออัดของเครือข่ายหรือความเสียหายของฮาร์ดแวร์ รายงานโหลดของบางโหนดอาจมาช้าหรือไม่มาถึงเลย
  • LBS จะข้ามโหนดเหล่านี้ระหว่างการอัปเดตค่าน้ำหนัก ทำให้น้ำหนักของเอนด์พอยต์ของโหนดนั้นไม่เปลี่ยนแปลง
  • อย่างไรก็ตาม หากรายงานโหลดหายไปจำนวนมาก การคำนวณค่าเฉลี่ยของการใช้งานอาจไม่แม่นยำ
  • เพื่อความปลอดภัย LBS จะข้ามขั้นตอนการอัปเดตค่าน้ำหนักทั้งหมดในกรณีนี้

เมตริกการใช้งาน

  • การใช้งาน CPU เป็นเมตริกโหลดบาลานซ์ที่ใช้แพร่หลายที่สุดที่ Dropbox
  • สำหรับบริการที่ไม่ได้ติดคอขวดที่ CPU จำนวนคำขอที่กำลังดำเนินการอยู่เป็นตัวชี้วัดทางเลือกที่ดี
  • LBS ถูกพัฒนาให้รองรับการทำโหลดบาลานซ์โดยอิงจาก CPU และ/หรือจำนวนคำขอที่กำลังดำเนินการอยู่

ข้อจำกัด

  • คอนโทรลเลอร์ PID สร้าง feedback loop เพื่อคงการใช้งานของโหนดให้อยู่ใกล้ค่าเป้าหมาย (ค่าเฉลี่ยของการใช้งาน)
  • หากมี feedback น้อยมาก เช่น บริการที่มีทราฟฟิกต่ำมาก หรือคำขอที่มี latency สูงมากซึ่งวัดเป็นระดับนาที การทำโหลดบาลานซ์จะไม่มีประสิทธิภาพ
  • บริการที่มีคำขอ latency สูงควรเป็นแบบ asynchronous

การกำหนดเส้นทางข้ามดาต้าเซ็นเตอร์

  • อินสแตนซ์ LBS จัดการโหลดบาลานซ์ภายในดาต้าเซ็นเตอร์
  • ส่วนการกำหนดเส้นทางข้ามดาต้าเซ็นเตอร์มีปัจจัยที่ต้องพิจารณาแตกต่างออกไป
    • ตัวอย่างเช่น ต้องการกำหนดเส้นทางคำขอไปยังดาต้าเซ็นเตอร์ที่ใกล้ที่สุดเพื่อลดเวลาไป-กลับของคำขอ
  • เพื่อให้ทำได้ Dropbox จึงเพิ่มการตั้งค่า locality ที่กำหนดการแบ่งทราฟฟิกระหว่างดาต้าเซ็นเตอร์ปลายทาง

การประเมินประสิทธิภาพของตัวโหลดบาลานซ์

  • ประสิทธิภาพของการโหลดบาลานซ์วัดด้วยอัตราส่วน max/avg
    • หากเจ้าของบริการเลือกการโหลดบาลานซ์โดยอิงตาม CPU จะใช้ maxCPU/avgCPU เป็นตัวชี้วัดประสิทธิภาพ
    • โดยทั่วไปเจ้าของบริการจะจัดสรรทรัพยากรให้บริการโดยอิงตามอัตราการใช้งานสูงสุดระหว่างโหนด เนื่องจากเป้าหมายหลักของการโหลดบาลานซ์คือการลดขนาดของฟลีต
  • กลยุทธ์การโหลดบาลานซ์ด้วย PID controller สามารถรักษาอัตราส่วน max/avg ให้ใกล้ 1 ได้

กราฟประเมินประสิทธิภาพการโหลดบาลานซ์

  • กราฟที่แสดงค่า max/avg CPU และ p95/avg CPU ของคลัสเตอร์ Envoy proxy ที่ใหญ่ที่สุด
    • หลังเปิดใช้งานการโหลดบาลานซ์ที่อิง PID controller เมตริกทั้งสองลดลงมาใกล้ 1
    • อัตราส่วน max/avg ลดจาก 1.26 เหลือ 1.01 แสดงให้เห็นการปรับปรุง 20%
  • กราฟที่แสดงการวิเคราะห์เปอร์เซ็นไทล์ของอัตราการใช้ CPU รายโหนด
    • หลังเปิดใช้งานการโหลดบาลานซ์ที่อิง PID controller ค่า max, p95, avg และ p5 แทบจะรวมเป็นเส้นเดียวกัน
  • อีกกราฟหนึ่งที่แสดงค่า max/avg CPU และ p95/avg CPU ของคลัสเตอร์ฐานข้อมูลฟรอนต์เอนด์ที่ใหญ่ที่สุด
    • หลังเปิดใช้งานการโหลดบาลานซ์ที่อิง PID controller เมตริกทั้งสองลดลงมาใกล้ 1
    • อัตราส่วน max/avg ลดจาก 1.4 เหลือ 1.05 แสดงให้เห็นการปรับปรุง 25%
  • อีกกราฟหนึ่งที่แสดงการวิเคราะห์เปอร์เซ็นไทล์ของอัตราการใช้ CPU รายโหนด
    • หลังเปิดใช้งานการโหลดบาลานซ์ที่อิง PID controller ค่า max, p95, avg และ p5 กลับมารวมเป็นเส้นเดียวกันอีกครั้ง

เหตุผลที่สร้าง Config Aggregator

  • Robinhood มีหลายตัวเลือกให้เจ้าของบริการเลือกใช้ และยังสามารถนำการเปลี่ยนแปลงไปใช้แบบไดนามิกได้
  • เจ้าของบริการสร้างและอัปเดตการตั้งค่า Robinhood ของบริการจาก service directory ภายใน codebase
  • การตั้งค่าเหล่านี้ถูกเก็บไว้ในบริการจัดการคอนฟิก ซึ่งเป็นไลบรารีที่สะดวกสำหรับรับการเปลี่ยนแปลงของคอนฟิก Robinhood แบบเรียลไทม์
  • อย่างไรก็ตาม ด้วยปัญหาบางประการ จึงไม่สามารถ build และ push mega config ของ Robinhood จาก codebase ได้เป็นประจำ
    • หากการเปลี่ยนแปลงถูกนำเข้ามาผ่านการ push คอนฟิก การกดปุ่ม rollback มีความเสี่ยง
      • เพราะไม่อาจทราบได้ว่ามีบริการอื่นเปลี่ยนไปมากน้อยเพียงใดนับจากการ push ครั้งล่าสุด
    • ทีมที่เป็นเจ้าของ Robinhood ต้องรับผิดชอบต่อการ push mega config แต่ละครั้งด้วย
      • ซึ่งหมายความว่าทีม Robinhood ต้องมีส่วนร่วมกับทุกการ push คอนฟิกที่เปลี่ยนแปลง และนั่นเป็นการสิ้นเปลืองเวลาเชิงวิศวกรรม
      • เพราะ incident ส่วนใหญ่เจ้าของบริการสามารถแก้ไขได้เอง
    • เพื่อให้ความเสี่ยงที่อาจเกิดขึ้นต่ำที่สุด การ push แต่ละครั้งใช้เวลาหลายชั่วโมงในการ deploy ไปยังหลายดาต้าเซ็นเตอร์
  • เพื่อแก้ปัญหาเหล่านี้ จึงสร้างบริการขนาดเล็กอีกตัวหนึ่งชื่อ Config Aggregator

Config Aggregator

  • Config Aggregator รวบรวมคอนฟิกแยกตามบริการทั้งหมด และประกอบเป็น mega config ที่ LBS จะใช้งาน
  • Config Aggregator เฝ้าติดตามคอนฟิกของแต่ละบริการ และกระจายการเปลี่ยนแปลงไปยัง mega config แบบเรียลไทม์
  • Config Aggregator ยังมีความสามารถ tombstone เพื่อป้องกันไม่ให้คอนฟิก Robinhood ของบริการถูกลบโดยไม่ตั้งใจ
    • หากเจ้าของบริการ push การเปลี่ยนแปลงที่ลบบริการออกจากคอนฟิก Robinhood, Config Aggregator จะทำเครื่องหมาย tombstone แทนการลบรายการบริการทันที
    • การลบจริงจะเกิดขึ้นหลังจากนั้นอีกหลายวัน
    • ฟีเจอร์นี้ยังช่วยแก้ race condition ที่อาจเกิดจากรอบการ push ที่ต่างกันระหว่างคอนฟิก Robinhood กับคอนฟิกการกำหนดเส้นทางอื่น ๆ (เช่น คอนฟิก Envoy)
  • ข้อเสียของบริการจัดการคอนฟิกคือปัจจุบันไม่มีการจัดการเวอร์ชัน
  • จึงสำรอง mega config เป็นระยะ เผื่อจำเป็นต้องย้อนคอนฟิก LBS กลับไปยังสถานะที่ทราบว่าปลอดภัย

กลยุทธ์การย้ายระบบ

  • การสลับกลยุทธ์การโหลดบาลานซ์ทั้งหมดในคราวเดียวอาจมีความเสี่ยง
  • นี่คือเหตุผลที่ Robinhood อนุญาตให้กำหนดหลายกลยุทธ์การโหลดบาลานซ์สำหรับบริการได้
  • Dropbox มี feature gate แบบอิงเปอร์เซ็นต์ จึงนำกลยุทธ์แบบผสมมาใช้ โดยให้ไคลเอนต์ใช้ผลรวมถ่วงน้ำหนักของค่าน้ำหนักที่สร้างจากสองกลยุทธ์การโหลดบาลานซ์เป็นค่าน้ำหนักของ endpoint
  • วิธีนี้ทำให้ย้ายไปสู่กลยุทธ์การโหลดบาลานซ์ใหม่ได้อย่างค่อยเป็นค่อยไป โดยที่ไคลเอนต์ทั้งหมดมองเห็นการกำหนดค่าน้ำหนักเดียวกันสำหรับ endpoint

สิ่งที่ได้เรียนรู้

  • ระหว่างการออกแบบและพัฒนา Robinhood ได้รับบทเรียนสำคัญหลายข้อเกี่ยวกับสิ่งที่ได้ผลและสิ่งที่ไม่ได้ผล
  • การให้ความสำคัญกับความเรียบง่าย ลดการเปลี่ยนแปลงฝั่งไคลเอนต์ให้เหลือน้อยที่สุด และวางแผนการย้ายระบบตั้งแต่แรก ช่วยให้การพัฒนาและ deploy LBS ง่ายขึ้น และหลีกเลี่ยงกับดักที่มีต้นทุนสูงได้

คอนฟิกควรเรียบง่ายที่สุดเท่าที่เป็นไปได้

  • Robinhood เพิ่มตัวเลือกจำนวนมากให้เจ้าของบริการตั้งค่าได้
  • แต่ในกรณีส่วนใหญ่ สิ่งที่พวกเขาต้องการคือค่าเริ่มต้นที่มีให้
  • คอนฟิกเริ่มต้นที่ดีและเรียบง่าย (หรือถ้าดีกว่านั้นคือไม่ต้องมีคอนฟิกเลย) สามารถประหยัดเวลาเชิงวิศวกรรมได้มหาศาล

การเปลี่ยนแปลงฝั่งไคลเอนต์ก็ควรรักษาให้เรียบง่ายเช่นกัน

  • การ rollout การเปลี่ยนแปลงไปยังไคลเอนต์ภายในอาจใช้เวลาหลายเดือน
    • deployment ส่วนใหญ่ถูก push ทุกสัปดาห์ แต่หลายระบบ deploy เพียงเดือนละครั้ง หรือบางครั้งไม่ deploy เลยเป็นเวลาหลายปี
  • ยิ่งย้ายการเปลี่ยนแปลงไปไว้ที่ LBS ได้มากเท่าไรยิ่งดี
    • ตัวอย่างเช่น ในช่วงแรกได้ตัดสินใจใช้ weighted round robin ในการออกแบบไคลเอนต์ และหลังจากนั้นก็ไม่เปลี่ยนอีกเลย
    • สิ่งนี้ช่วยเพิ่มความเร็วของการดำเนินงานอย่างมาก
  • การจำกัดการเปลี่ยนแปลงส่วนใหญ่ไว้ที่ LBS ยังช่วยลดความเสี่ยงด้านเสถียรภาพด้วย
    • เพราะหากจำเป็น การเปลี่ยนแปลงใน LBS สามารถ rollback ได้ภายในไม่กี่นาที

การย้ายระบบควรถูกวางแผนตั้งแต่ขั้นตอนออกแบบโครงการ

  • การย้ายระบบใช้เวลาเชิงวิศวกรรมมหาศาล
  • และยังมีความเสี่ยงด้านเสถียรภาพที่ต้องคำนึงถึง
  • แม้จะไม่ใช่งานที่สนุก แต่เป็นงานสำคัญ
  • เมื่อต้องออกแบบบริการใหม่ ควรพิจารณาให้เร็วที่สุดว่าจะย้าย use case เดิมไปยังบริการใหม่อย่างราบรื่นได้อย่างไร
  • ยิ่งมีข้อกำหนดที่ต้องให้เจ้าของบริการทำมากเท่าไร การย้ายระบบก็ยิ่งกลายเป็นฝันร้าย
    • โดยเฉพาะเมื่อเป็นคอมโพเนนต์โครงสร้างพื้นฐานพื้นฐาน
  • กระบวนการย้ายระบบของ Robinhood ไม่ได้ถูกออกแบบไว้อย่างดีตั้งแต่แรก จึงใช้เวลามากกว่าที่คาดไว้มากในการนำกระบวนการกลับมาออกแบบใหม่และออกแบบคอนฟิกใหม่
  • เวลาทางวิศวกรรมที่ต้องใช้ในการย้ายระบบควรเป็นตัวชี้วัดสำคัญของความสำเร็จ

ผลลัพธ์ของ Robinhood

  • หลังใช้งานในโปรดักชันมาราว 1 ปี สามารถกล่าวได้ว่า Robinhood เวอร์ชันล่าสุดสามารถแก้ปัญหาการโหลดบาลานซ์ที่ Dropbox เผชิญมานานได้อย่างมีประสิทธิภาพ
  • อัลกอริทึม PID controller ซึ่งเป็นแกนหลัก แสดงผลลัพธ์ที่น่าสนใจ และแสดงการปรับปรุงประสิทธิภาพอย่างมีนัยสำคัญในบริการขนาดใหญ่ที่สุด
  • ยังได้รับข้อมูลเชิงลึกอันมีค่าเกี่ยวกับการออกแบบและการปฏิบัติการบริการโหลดบาลานซ์ในระดับขนาดของ Dropbox

เชิงอรรถ

  1. ให้ N, M และ s แทนจำนวนเซิร์ฟเวอร์ จำนวนไคลเอนต์ และขนาดของส่วนย่อยของที่อยู่ตามลำดับ จำนวนไคลเอนต์ที่เซิร์ฟเวอร์เชื่อมต่ออยู่เป็นไปตามตัวอย่างของการแจกแจงทวินาม B(M, s/n) ดังที่กล่าวไว้ก่อนหน้านี้ ไคลเอนต์ทำ simple round robin กับชุดที่อยู่ที่ service discovery ให้มา ดังนั้นหากไคลเอนต์แต่ละตัวส่งคำขอในปริมาณใกล้เคียงกัน การกระจายโหลดฝั่งเซิร์ฟเวอร์จะมีลักษณะคล้ายการแจกแจงทวินาม

  2. ขยายระบบ service discovery เดิมเพื่อรองรับโปรโตคอล gRPC xDS (A27) ณ เวลาที่เขียนบล็อกนี้ gRPC client ยังไม่รองรับ weighted round robin สำหรับค่าน้ำหนัก endpoint จาก control plane จึงได้พัฒนา custom weighted round robin picker โดยอิงจากการจัดตารางแบบ earliest deadline first

  3. มีกรณีที่น่าสนใจซึ่งบริการเกิดอาการค้างเป็นช่วง ๆ เพราะ I/O ที่ประสิทธิภาพลดลง ในสถานการณ์นี้ CPU ของโหนดดังกล่าวจะยังคงต่ำ และ LBS จะเริ่มเพิ่มค่าน้ำหนักของโหนดเพื่อดัน CPU ขึ้นสู่ค่าเฉลี่ย จนนำไปสู่ dead spiral วิธีแก้คือใช้ค่าสูงสุดของ CPU และจำนวนคำขอที่กำลังดำเนินการอยู่เป็นตัววัดโหลดเพื่อทำให้บริการสมดุล

ความเห็นของ GN⁺

  • Robinhood ดูเป็นบริการที่ยอดเยี่ยมซึ่งแก้ปัญหาโหลดบาลานซ์ของ Dropbox ได้อย่างมีประสิทธิภาพ การนำ PID controller มาใช้เป็นจุดที่น่าประทับใจ
  • นี่เป็นกรณีศึกษาที่แสดงให้เห็นได้ชัดว่าโหลดบาลานซ์ในโครงสร้างพื้นฐานระดับโลกขนาดใหญ่นั้นเป็นโจทย์ที่ยากเพียงใด มีหลายปัจจัยที่ต้องคำนึงถึง เช่น ความแตกต่างของฮาร์ดแวร์ การกระจายโหลดที่ไม่สมดุล และความหนาแน่นของเครือข่าย
  • ดูเหมือนว่าสิ่งสำคัญคือการออกแบบให้ทุกคอมโพเนนต์เชื่อมโยงกันอย่างเป็นระบบและทำงานร่วมกันได้ดี แม้ LBS, พร็อกซี และ routing DB จะแยกจากกัน แต่ก็โต้ตอบกันอย่างใกล้ชิดแบบเรียลไทม์
  • กราฟที่ใช้ประเมินประสิทธิภาพโหลดบาลานซ์เชิงปริมาณและแสดงภาพการปรับปรุงต่าง ๆ น่าประทับใจมาก โดยเฉพาะการแสดงให้เห็นอย่างชัดเจนว่าการรักษาอัตราส่วน max/avg ให้ใกล้ 1 มีความสำคัญต่อการปรับขนาด fleet ให้เหมาะสม
  • การนำ Config Aggregator มาใช้เพื่อแยกการตั้งค่าตามแต่ละบริการก็ดูเป็นไอเดียที่ดี ช่วยให้เจ้าของบริการสามารถจัดการการเปลี่ยนแปลงของตนเองได้อย่างอิสระ
  • การมีมาตรการป้องกันอย่าง tombstone ก็เป็นรายละเอียดที่ใส่ใจเช่นกัน การป้องกันไม่ให้การตั้งค่าถูกลบโดยความผิดพลาดเป็นเรื่องสำคัญ
  • บทเรียนเกี่ยวกับกลยุทธ์การย้ายระบบก็ดูมีประโยชน์ หากไม่คำนึงถึงการย้ายระบบตั้งแต่แรก ภายหลังก็อาจต้องเสียเวลาไปมาก
  • โดยรวมแล้ว Robinhood ดูเป็นโซลูชันที่เป็นระบบและออกแบบมาอย่างประณีตสำหรับการทำโหลดบาลานซ์ในระดับของ Dropbox และเป็นกรณีศึกษาที่บริษัทอื่นซึ่งมีโครงสร้างพื้นฐานขนาดใหญ่สามารถนำไปอ้างอิงได้

โซลูชันที่คล้ายกัน:

  • Elastic Load Balancing (ELB) ของ AWS และ Cloud Load Balancing ของ Google Cloud ก็มีบริการแบบ managed service สำหรับการทำโหลดบาลานซ์ในระดับใหญ่เช่นกัน
  • ในกรณีของ Kubernetes แม้จะมีโหลดบาลานเซอร์ของตัวเอง (kube-proxy) แต่หากใช้โซลูชัน service mesh เช่น Istio หรือ Linkerd ก็จะสามารถใช้ความสามารถด้านโหลดบาลานซ์และการจัดการทราฟฟิกที่ทรงพลังยิ่งขึ้นได้
  • Zuul ของ Netflix และ Envoy ของ Lyft ก็มีความสามารถด้านโหลดบาลานซ์แบบพร็อกซีเป็นฐานเช่นกัน

ข้อควรพิจารณาเมื่อเริ่มใช้งาน:

  • จำเป็นต้องตรวจสอบความเข้ากันได้กับโครงสร้างพื้นฐานและบริการเดิม และหากต้องมีการย้ายระบบก็ควรวางกลยุทธ์ไว้
  • ต้องทดสอบและมอนิเตอร์ผลกระทบต่อประสิทธิภาพและเสถียรภาพอย่างเพียงพอ บั๊กในตรรกะโหลดบาลานซ์อาจร้ายแรงได้
  • ควรกำหนดขอบเขตและความเร็วในการนำมาใช้โดยพิจารณาจากศักยภาพของทีม การค่อย ๆ ใช้งานเป็นขั้นตอนน่าจะดีกว่าการนำไปใช้กับทั้งหมดอย่างเร่งรีบ
  • ในระยะยาวจำเป็นต้องมีความพยายามในการปรับให้เหมาะสมและพัฒนาอย่างต่อเนื่อง เช่น การจูนอัลกอริทึมโหลดบาลานซ์ให้เหมาะกับสถานการณ์ และการกำจัดคอขวดจะช่วยได้

1 ความคิดเห็น

 
kbumsik 2024-11-01

ได้ยินเรื่องตัวควบคุม PID ในฝั่งซอฟต์แวร์ด้วยแฮะ 55