วิธีหลีกเลี่ยง“ ลองพายุอีกครั้ง” ในบริการแบบกระจายได้อย่างไร


10

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

ใช้ตัวอย่างนี้:

ตัวอย่างสถาปัตยกรรม

หากตัวอย่างเช่นบริการโดยรวมได้รับการปรับขนาดเพื่อรองรับ 80,000 คำขอต่อวินาทีและทำงานที่ความจุประมาณ 80% การรับส่งข้อมูลที่ขัดขวางการรับบริการที่ได้รับ 101,000 คำขอต่อวินาทีจะทำให้ 1,000 คำขอเหล่านั้นล้มเหลว

เมื่อนโยบายลองใหม่เริ่มต้นขึ้นคุณจะจบลงด้วยการร้องขอมากกว่า 1,000+ ครั้งขึ้นอยู่กับที่ตรวจพบความล้มเหลวซึ่งจะผลักดันบริการโดยรวมสูงสุดถึง 102,000 คำขอต่อวินาที - จากนั้นบริการของคุณจะทวีความรุนแรงขึ้นเป็นสองเท่า คำขอที่ล้มเหลวทุกวินาที

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


หาก 100kQPS เป็น 80% ของความจุดังนั้น 101kQPS ไม่ควรส่งผลให้เกิดความล้มเหลว 1k มันควรจะทำให้เกิดความล้มเหลวเป็นศูนย์ - นั่นไม่ใช่ประเด็นของการแก้ไขปัญหามากเกินไปหรือไม่?
เอเดรียน

@ เอเดรียที่ถูกต้องของคุณมันเป็นตัวอย่างที่ได้อธิบายไว้ในการอธิบายประเด็น - ฉันพยายามที่จะลดทอนพอที่จะทำให้ประเด็นของฉันชัดเจนโดยไม่เป็นนามธรรมมากเกินไป ฉันได้แก้ไข "อัตราส่วนเพื่อรองรับ 100,000" เป็น "อัตราส่วนเพื่อรองรับ 80,000"
Richard Slater

คำตอบ:


7

ขึ้นอยู่กับสิ่งที่คุณพยายามหลีกเลี่ยง

หากคุณกำลังพยายามหลีกเลี่ยงการแทรกแซงบริการบางอย่างซึ่งเป็นบริการที่สำคัญอย่างแท้จริง (ฉันคิดในแง่ของ "ผู้คนจะตายถ้าการเรียก API ของฉันไม่เหมาะสม") คุณต้องใช้งบประมาณเพียงเท่านี้ มาจากการจัดสรรทรัพยากรที่ทุ่มเทอย่างมากมาย และใช่พวกเขาต้องได้รับการอุทิศไม่มีสิ่งนี้ที่อนุญาตให้มีการจราจรติดขัดสิ่งบริการที่หลากหลายซึ่งจะทำให้เกิดไฟฟ้าดับ

ในสถานการณ์ที่เป็นไปได้มากกว่าที่การให้บริการของคุณหยุดทำงานจะไม่สะดวกคุณสามารถแก้ไขปัญหาทั้งจากฝั่งไคลเอ็นต์และฝั่งเซิร์ฟเวอร์ แม้ว่าจะเป็นเรื่องที่น่าสังเกตว่ามันเป็นไปไม่ได้ในทางตรรกะที่จะแก้ปัญหาการรับส่งข้อมูลจำนวนมากเพราะไม่มีการประมวลผลปริมาณการใช้งาน (ซึ่งใช้ทรัพยากร) คุณไม่สามารถทราบได้ว่าเป็นการลองอีกครั้งหรือไม่ โดยลูกค้าหากเป็น DDOS เป็นต้น แต่คุณสามารถลดผลกระทบได้

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

สำหรับโครงสร้างพื้นฐานด้านเซิร์ฟเวอร์ของคุณทางออกที่ง่ายที่สุดคือการเค้น โดยเฉพาะอย่างยิ่งถ้าคุณสามารถลองและกระจายพวกเขาอย่างมีเหตุผลตามกรณีการใช้งานเฉพาะของคุณ (เช่นถ้าคุณมีบริการแบบรวมศูนย์ในการตัดสินใจอย่างหนักคุณต้องการเริ่มบล็อกคำขอทางภูมิศาสตร์ที่ห่างไกลซึ่งอาจทำให้เธรดแขวนอยู่ ฝั่งเซิร์ฟเวอร์หรือคุณต้องการกระจายกระแสไฟฟ้าที่หลีกเลี่ยงไม่ได้ของคุณอย่างเท่าเทียมกันหรือไม่ ฯลฯ ) โดยทั่วไปแล้วการกลับมาของ 503 โดยเจตนาจากเกตเวย์นั้นเป็นสิ่งที่ถูกกว่าการขอผ่านและส่ง 504 อย่างไรก็ตาม. โดยทั่วไปบังคับให้ลูกค้าปฏิบัติตามสิ่งที่คุณสามารถให้และตอบสนองที่ถูกต้องในปัจจุบันเพื่อให้ลูกค้าสามารถตอบสนองได้อย่างเหมาะสม


5

วิธีหนึ่งในการป้องกันพายุที่ลองใหม่เหล่านี้คือการใช้กลไกการถอยกลับ

จากส่วนการนำ backoff ไปใช้งานในการลองใหม่ในคู่มือการออกแบบ Google App Engine for Scale :

รหัสของคุณสามารถลองอีกครั้งเมื่อเกิดความล้มเหลวไม่ว่าจะเป็นการเรียกบริการเช่น Cloud Datastore หรือบริการภายนอกโดยใช้การดึง URL หรือ Socket API ในกรณีนี้คุณควรดำเนินนโยบาย backoff สุ่มชี้แจงในการสั่งซื้อเพื่อหลีกเลี่ยงปัญหาฟ้าร้องฝูง คุณควร จำกัด จำนวนการลองใหม่ทั้งหมดและจัดการกับความล้มเหลวหลังจากถึงขีด จำกัด การลองใหม่สูงสุด

GAE APIs ส่วนใหญ่มีการเปิดใช้งานกลไก / นโยบายการแบ็คออฟดังกล่าวอยู่แล้วตามค่าเริ่มต้น


ขอขอบคุณการใช้กลไกย้อนกลับเป็นคำแนะนำที่ดีผมมักจะไปสำหรับ backoff ชี้แจงการกำหนดค่าใช้Transient ความผิดพลาดการจัดการบล็อกโปรแกรมประยุกต์ อย่างไรก็ตามจากประสบการณ์การดำเนินงานมากกว่า 5 ปีในการใช้งานแอพพลิเคชั่นไฮเปอร์สเกลใน Azure ถึงแม้จะมีการถอยกลับที่อธิบายว่า "ลองใหม่อีกครั้ง" ยังคงเกิดขึ้นค่อนข้างบ่อย - ฉันไม่เคยพบกลยุทธ์ที่ใช้งานได้
Richard Slater
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.