งานวิจัยเกี่ยวกับวิธีรีลีสของ Facebook แบบไม่มีดาวน์ไทม์
(dropbox.com)Zero Downtime Release: Disruption-free Load Balancing of a Multi-Billion User Website
คำอธิบายสรุป
-
เซิร์ฟเวอร์มักต้องรีสตาร์ตอยู่บ่อยครั้ง: อัปเกรด, แก้บั๊ก, แพตช์ความปลอดภัย
-
จากการนำ Continuous Release มาใช้
→ ในกรณีของ Facebook จากเดิมที่ในปี 2007 ปล่อยดีพลอยสัปดาห์ละ 1 ครั้ง กลายเป็นมากกว่า 100 ครั้งต่อสัปดาห์
→ เซิร์ฟเวอร์หลายล้านเครื่องถูกรีสตาร์ตทุกวัน
→ AWS, Atlassian, Yelp, Ebay, Uber ก็เช่นกัน
→ ทำให้ health check ล้มเหลวเป็นพักๆ ได้
- วิธีดีพลอยแบบดั้งเดิม
- Blue/Green deployment (AWS CodeDeploy, Kubernetes): แบ่งเป็นสองกลุ่มเครื่อง แล้ว load balancer ย้ายทราฟฟิกไปฝั่งที่อัปเดตก่อน → มีต้นทุนสูง ไม่เหมาะกับ Edge ที่มีเครื่องจำนวนมาก
- Rolling Updates (Envoy, NGINX, Apache, Kubernetes, AWS): ค่อยๆ อัปเดตทีละเครื่องพร้อมให้ load balancer ปรับทราฟฟิกตาม
→ ระหว่างอัปเดตการใช้ CPU จะลดลง และการวนรอบพัฒนาช้า
- Hot Restart (HAProxy, Envoy): รันโปรเซสเวอร์ชันใหม่ในเครื่องเดียวกัน แล้วเมื่อทราฟฟิกของโปรเซสเดิมค่อยๆ หมดลง โปรเซสใหม่จึงรับทราฟฟิกต่อ (SO_REUSEPORT, CMSG, SCM_RIGHTS)
→ ใช้ได้กับ TCP เท่านั้น และกับ UDP อาจเกิดการ route ผิดพลาดได้
"จะทำอย่างไรให้การอัปเดตรีลีสทำได้แบบไม่มีดาวน์ไทม์, มีการวนรอบที่รวดเร็ว, และไม่เกิดการหยุดชะงัก?"
- โครงสร้างพื้นฐานด้านทราฟฟิกของ Facebook
- Edge PoP(L7 LB, ProxyGen) - Data Center(L7 LB, ProxyGen) - App. Server(HHVM,MQTT)
→ รีสตาร์ตแยกตามแต่ละ tier เพื่อป้องกันการหยุดชะงัก
→ เครื่องของ Edge และ Data Center จะรัน ProxyGen ตัวใหม่ขึ้นมาเพื่อทำ "Socket TakeOver" → ระหว่าง Edge กับ Data Center ใช้ "Downstream Connection Reuse" → การเชื่อมต่อระหว่าง Data Center กับ App Server ใช้ "Partial Post Replay"
- Socket Takeover: รันโปรเซสใหม่ขึ้นมาแล้วรับช่วง TCP listening socket และ UDP VIP socket ผ่าน SCM_RIGHTS และ CMSG
→ SCM_RIGHTS: ประเภทซ็อกเก็ตที่ทำให้รับส่ง file descriptor ของอีกโปรเซสได้
→ CMSG: ทำให้ส่ง control message ระหว่างโปรเซสในเครื่องเดียวกันได้ด้วยความสามารถของ sendmsg()
→ สำหรับ QUIC ซึ่งเป็นคอนเน็กชันบน UDP ในกรณีของคอนเน็กชันเดิม โปรเซสใหม่จะถาม QUIC ConnectionID จากโปรเซสเดิม แล้ว forward packet นั้นไปยังโปรเซสเดิม
- Partial Post Replay (รีสตาร์ต App server)
→ App server มีเวิร์กโหลด 2 แบบ: การเรียก API แบบสั้น และการเรียก HTTP POST แบบยาว (อัปโหลด)
→ App server นี้ไม่มีทรัพยากรเหลือพอ จึงไม่สามารถรันอินสแตนซ์ใหม่แล้วส่งต่อซ็อกเก็ตแบบ Socket Takeover ได้ และเวลาการอัปโหลดที่ยาวนานก็เป็นปัญหาด้วย
→ หาก App server ถูกอัปเดตระหว่างการอัปโหลดระยะยาว เนื่องจากพร็อกซีไม่ได้เก็บเนื้อหาทั้งหมดไว้ จึงยุติ POST นั้น พร้อมส่งโค้ด 379 และส่งข้อมูลที่รับมาจนถึงตอนนั้นกลับไปยังพร็อกซี
→ พร็อกซีจะรวมข้อมูลที่ได้รับจาก App server เดิมเข้ากับข้อมูลที่เหลือ แล้วพยายามส่งใหม่ไปยังเครื่องใหม่อีกครั้ง
- ข้อดีของ Zero Downtime Release
→ ใช้งาน CPU สูงกว่า Rolling Update ประมาณ 20%
→ เมื่อเทียบกับ Hot Restart ที่เคย route ผิดพลาดของ QUIC packet ได้ถึง 20K วิธีนี้แทบไม่มีการ route ผิดเลย
→ ภายใน Facebook มีการใช้ Socket TakeOver มาตั้งแต่ปี 2013 และส่วนที่เหลือเริ่มใช้ตั้งแต่ปี 2015
1 ความคิดเห็น
เนื้อหาข้างต้นเป็นการสรุปโดยอิงจากวิดีโออธิบายความยาว 20 นาทีนี้ https://dl.acm.org/action/downloadSupplement/…
ProxyGen : ไลบรารี HTTP C++ ของ Facebook https://github.com/facebook/proxygen