- วิศวกรระบบกระจายมักได้เรียนรู้จากบาดแผลที่เกิดจากความผิดพลาดในงานจริงอยู่บ่อยครั้ง
- บทความนี้เขียนขึ้นเพื่อช่วยให้วิศวกรรุ่นใหม่ไม่ต้องเผชิญบาดแผลแบบนั้น
ระบบกระจายล้มเหลวบ่อย
- ระบบกระจายมีโอกาสล้มเหลวสูงกว่างานวิศวกรรมซอฟต์แวร์ด้านอื่น โดยเฉพาะโอกาสของความล้มเหลวบางส่วน
- วิศวกรระบบที่ไม่เคยทำงานกับ distributed computing มักเสนอไอเดียอย่าง "ก็แค่ส่ง write ไปยังสองระบบ" หรือ "retry การเขียนไปเรื่อย ๆ จนกว่าจะสำเร็จ"
- ระบบเครือข่ายล้มเหลวบ่อยกว่าเครื่องเดี่ยว และความล้มเหลวเหล่านี้ก็มักเป็นแบบบางส่วน
- การเขียนหนึ่งครั้งอาจสำเร็จ แต่อีกครั้งอาจล้มเหลว แล้วเราจะทำอย่างไรเพื่อให้ได้มุมมองของข้อมูลที่สอดคล้องกัน? ความล้มเหลวบางส่วนแบบนี้ให้เหตุผลได้ยากกว่ามาก
- ปัญหาอาจเกิดจากสวิตช์ล่ม, ผู้นำ "หายไป" เพราะ garbage collection, หรือการเขียนผ่านซ็อกเก็ตที่ดูเหมือนสำเร็จแต่จริง ๆ แล้วล้มเหลว การอ่านจากหน่วยความจำภายในเครื่องเชื่อถือได้กว่าการอ่านผ่านสวิตช์หลายตัวมาก
- ต้อง "ออกแบบโดยเผื่อความล้มเหลว"
การสร้างระบบกระจายที่แข็งแรงมีต้นทุนสูงกว่า
- การสร้างโซลูชันแบบกระจายที่แข็งแรงมีต้นทุนสูงกว่าโซลูชันบนเครื่องเดียว
- เทคโนโลยี virtual machine และ cloud ทำให้งานวิศวกรรมระบบกระจายถูกลง แต่ก็ยังต้องใช้ต้นทุนสูงอยู่ดี
- การจำลองมีประโยชน์ แต่ไม่สามารถแก้ปัญหาทั้งหมดที่เกิดในสภาพแวดล้อมแบบกระจายจริงได้
ระบบกระจายโอเพนซอร์สที่แข็งแรงนั้นหาได้ยาก
- ค่าใช้จ่ายในการรันเครื่องจำนวนมากเป็นเวลานานเป็นภาระสำหรับชุมชนโอเพนซอร์ส
- คนที่เขียนโค้ดโอเพนซอร์สเป็นงานอดิเรกมักไม่มีทรัพยากรทางการเงินพอจะสำรวจหรือแก้ปัญหามากมายของระบบกระจาย
- บางปัญหาได้รับการแก้โดยวิศวกรในบริษัท แต่ลำดับความสำคัญของพวกเขาก็ไม่ได้สอดคล้องกันเสมอไป
การประสานงานนั้นยากมาก ควรหลีกเลี่ยงให้มากที่สุด
- หัวใจของการขยายระบบในแนวนอนคือความเป็นอิสระ ต้องลดการสื่อสารและการตกลงกันระหว่างเครื่องให้น้อยที่สุด
- ทุกครั้งที่เครื่องสองเครื่องต้องตกลงกันเรื่องบางอย่าง การทำบริการนั้นก็ยากขึ้น
- อัลกอริทึม Paxos นั้นนำไปใช้งานจริงได้ยากมาก
ถ้าปัญหาใส่ไว้ในหน่วยความจำได้ มันก็มักเป็นปัญหาง่าย
- สำหรับวิศวกรระบบกระจาย ปัญหาที่จำกัดอยู่แค่เครื่องเดียวถือว่าง่าย
- เมื่อข้อมูลอยู่ห่างออกไปหลายสวิตช์ การประมวลผลข้อมูลให้รวดเร็วจะยากขึ้น
"ความช้า" คือปัญหาที่ยากที่สุด
- "ความช้า" อาจหมายถึงมีอย่างน้อยหนึ่งระบบจากหลายระบบที่เกี่ยวข้องกับคำขอของผู้ใช้ทำงานช้า
- ความล้มเหลวบางส่วนจะไม่ปรากฏในกราฟ และกว่าจะชัดเจนก็มักยากที่จะได้ทรัพยากรที่จำเป็นมาใช้แก้ปัญหา
ต้องทำ backpressure ให้ครอบคลุมทั้งระบบ
- backpressure หมายถึงการที่ระบบผู้ให้บริการส่งสัญญาณความล้มเหลวกลับไปยังระบบที่ร้องขอ และระบบผู้ร้องขอต้องรู้วิธีจัดการกับความล้มเหลวนั้น
- หากไม่มีกลไก backpressure ก็มีโอกาสสูงที่จะเกิดความล้มเหลวต่อเนื่องหรือการสูญหายของข้อความโดยไม่ตั้งใจ
ต้องหาวิธีให้ระบบยังใช้งานได้บางส่วน
- หมายถึงความสามารถในการส่งคืนผลลัพธ์บางส่วนได้ แม้ว่าส่วนหนึ่งของระบบจะล้มเหลวก็ตาม
- ตัวอย่างเช่น ระบบค้นหาอาจส่งคืนผลลัพธ์ที่รวบรวมได้ หากไม่สามารถค้นหาเอกสารทั้งหมดได้ภายในเวลาที่กำหนด
metrics คือวิธีเดียวที่จะทำงานให้สำเร็จได้
- การเปิดเผย metrics คือวิธีเดียวที่จะเข้าใจได้ว่าระบบทำงานจริงอย่างไร
- ไฟล์ล็อกมีประโยชน์ แต่ก็มักโกหกได้ บันทึกความสำเร็จมักซ้ำกันในกรณีส่วนใหญ่จึงไม่ได้ถูกเก็บไว้
ควรใช้ percentile แทนค่าเฉลี่ย
- percentile แม่นยำและมีประโยชน์กว่าค่าเฉลี่ย ค่าเฉลี่ยมักนำไปสู่การตัดสินใจที่ผิดพลาด
ต้องเรียนรู้วิธีประเมินความจุ
- การรู้ว่าต้องใช้เครื่องกี่เครื่องเพื่อทำงานให้สำเร็จเป็นเรื่องสำคัญ
- ตัวอย่างเช่น มักต้องคำนวณคร่าว ๆ บนกระดาษเปล่าว่าสามารถเก็บ tweet ID ไว้ในหน่วยความจำได้มากแค่ไหน
feature flag คือวิธีการ rollout โครงสร้างพื้นฐาน
- feature flag เป็นวิธีทั่วไปในการ rollout ฟีเจอร์ใหม่เข้าสู่ระบบ
- การใช้ feature flag ช่วยเพิ่มความมั่นใจต่อโปรเจ็กต์และลดต้นทุนของความล้มเหลว
ต้องเลือก ID space อย่างชาญฉลาด
- ID space ของระบบเป็นตัวกำหนดโครงสร้างของระบบ
- ตัวอย่างเช่น tweet ID ของ Twitter API เป็นเพียงตัวเลข 64 บิตธรรมดา ๆ ที่ไม่ได้ผูกกับข้อมูลอื่น
ต้องใช้ประโยชน์จาก data locality
- การให้การประมวลผลและแคชข้อมูลอยู่ใกล้กับ persistent storage จะมีประสิทธิภาพมากกว่า
- เครือข่ายมีความล้มเหลวและความหน่วงมากกว่าการ dereference pointer และ
fread(3)
การเขียนข้อมูลที่แคชไว้กลับลง persistent storage เป็นเรื่องไม่ดี
- ปัญหานี้เกิดขึ้นในหลายระบบ โดยเฉพาะระบบที่ออกแบบโดยคนที่มีประสบการณ์ด้านระบบกระจายน้อย
คอมพิวเตอร์ทำอะไรได้มากกว่าที่คิด
- มีข้อมูลที่คลาดเคลื่อนมากมายเกี่ยวกับความสามารถของคอมพิวเตอร์จากผู้ปฏิบัติงานที่ยังมีประสบการณ์น้อย
- เว็บเซิร์ฟเวอร์สมัยใหม่สามารถจัดการคำขอหลายพันรายการได้ภายในเวลาไม่กี่ร้อยมิลลิวินาที
ควรใช้ทฤษฎีบท CAP เพื่อวิจารณ์ระบบ
- ทฤษฎีบท CAP ไม่ใช่สิ่งที่ใช้เพื่อสร้างระบบ แต่มีประโยชน์ในการวิจารณ์การออกแบบระบบกระจาย
ควรแยกบริการออกมา
- บริการในที่นี้หมายถึงระบบกระจายที่มีตรรกะระดับสูงกว่าระบบจัดเก็บข้อมูล
- การแยกบริการออกมาสามารถ deploy ได้เร็วและง่ายกว่าการสร้างเป็นไลบรารี
สรุปโดย GN⁺
- วิศวกรรมระบบกระจายแตกต่างจากงานวิศวกรรมซอฟต์แวร์ด้านอื่น เพราะมีโอกาสล้มเหลวสูงและเกิดความล้มเหลวบางส่วนได้บ่อย
- การสร้างระบบกระจายที่แข็งแรงมีต้นทุนสูงกว่า และพบได้ไม่บ่อยในชุมชนโอเพนซอร์ส
- การเข้าใจและนำแนวคิดอย่างการประสานงาน, data locality, backpressure และการพร้อมให้บริการบางส่วนไปใช้เป็นสิ่งสำคัญ
- การใช้ metrics และ percentile, การใช้ feature flag, และการเลือก ID space อย่างเหมาะสม ช่วยเพิ่มทั้งประสิทธิภาพและความเสถียรของระบบ
- ควรใช้ทฤษฎีบท CAP เพื่อวิจารณ์ระบบ และแยกบริการออกมาเมื่อจำเป็น
1 ความคิดเห็น
ความคิดเห็นบน Hacker News
หลักการ CALM (Consistency as Logical Monotonicity) เข้าใจง่ายกว่า CAP และเป็นผลลัพธ์ที่เป็นพื้นฐานยิ่งกว่า
การส่งมอบแบบ exactly-once เป็นไปไม่ได้ และต้องเลือกอย่างใดอย่างหนึ่งระหว่าง at-most-once หรือ at-least-once
เป็นบทความที่ดี แม้จะเขียนเมื่อ 8 ปีก่อน แต่ก็ยังมีเนื้อหาจำนวนมากที่ยังใช้ได้อยู่
ลิงก์ไปยังการสนทนาในอดีต:
ชอบคำอธิบายที่ใช้งานได้จริงและอยู่บนความเป็นจริง ไม่มีคำฮิตอย่าง "microservices"
ตอนทำงานที่ Lookout, Jeff Hodges ได้นำเสนอบทความนี้
เคยมีประสบการณ์ร่วมงานกับผู้เขียนบทความนี้
หลายอย่างเปลี่ยนไปมากตั้งแต่ปี 2013