作者 / Manuel Correa,Arthur Gonigberg,Daniel West
譯者 / Alpha
原文鏈接/https://netflixtechblog.com/keeping-netflix-reliable-using-prioritized-load-shedding-6cc827b02f94
對世界各地的司機來說,堵車是最令人沮喪的經歷之一。每個人都緩慢得像是在爬行一樣,有時是因為出現了一個小問題,有時則是毫無理由的擁堵。作為Netflix的工程師,我們一直在不斷評估如何重新設計流量管理框架。如果我們知道每個人行程的緊迫性,就可以有針對性地為他們選擇路線,而不是讓大家做無謂的等待,這么做的結果會如何呢?
在Netflix的工程設計中,我們的動力是確保Netflix可以在您需要的時候及時出現。然而,就在去年,我們的系統還很容易受到人們所說的的“交通擁堵”的影響;我們有開關斷路器,但沒有循序漸進的方式來減輕負載。為了改善會員的播放體驗,我們引入了基于優先級的漸進式減載法。
下面的動畫展示了當后端根據優先級限制流量時,觀眾體驗到的Netflix性能。當較低優先級的請求被限制時,整個播放體驗完整流暢,觀眾可以盡情享受觀看的內容。接下來讓我們深入研究一下我們是如何做到這一點的。
觸發失敗的誘因有很多,比如客戶端行為不當引發的重試風暴、后臺服務器規模不足、部署不當、網絡故障或云提供商的問題等等。任何上述原因都可能瞬即給系統造成巨大的載荷,在以前,這些例子中的每一個都會使我們的會員無法播放視頻。為了防止此類突發事件的發生,我們開始著手實現以下目標,使Netflix的服務更具彈性:
- 跨設備(移動、瀏覽器和電視)持續確定請求的優先級
- 根據優先級逐步限制請求
- 通過對特定優先級的請求進行紊亂測試(Chaos Testing)(有意的故障輸入)來驗證假設
我們設想的,包含優先級節流和紊亂測試的最終架構,如下所示。
具有優先級節流和紊亂測試的高級播放端架構
構建請求分類
我們決定聚焦于三個維度來對請求流量進行分類:吞吐量、功能性和重要性。根據這些特征,流量被分為以下幾類:
- 非關鍵型請求:該類型流量不影響播放或會員體驗,日志和后臺請求就屬于此類流量。此類請求通常有較高的吞吐量,是系統負載來源中占據比例較大的部分。
- 體驗降級型請求:該類型流量影響會員體驗,但不影響播放功能。此類請求流量常用于以下功能:停止和暫停標記、播放器中的語言選擇、觀看歷史記錄等。
- 關鍵型請求:流量影響播放功能。如果請求失敗,會員在點擊播放時會看到一條錯誤消息。
API網關服務(Zuul)根據請求的屬性,將其分為非關鍵型請求、體驗降級型請求和關鍵型請求,并根據每個請求的單獨特征,計算它們從1到100之間的優先級分數。計算是任務開始的第一步,以便在其余關于請求的工作流程中來使用。
大多數情況下,請求的工作流在不考慮請求優先級的情況下,也可以正常運行。然而,就像任何服務器一樣,有時我們會遇到這樣的情況:我們的兩個后端中有一個遇到了麻煩,或者Zuul本身也遇到了麻煩。當這種情況發生時,具有更高優先級的請求將得到優先處理。優先級較高的請求將得到服務,而優先級較低的請求不會被接待。它的執行,類似于具有動態優先級閾值的優先級隊列,允許Zuul丟棄優先級低于當前閾值的請求。
尋找最佳的流量控制點
在請求的整個生命周期中,Zuul有兩個時間點可以執行負載分流:當它將請求,路由到特定的后端服務器時(服務器節流),或者在初始請求處理時,這會影響所有后端服務(全局節流)。
服務器節流
通過監控錯誤率和對后端服務的并發請求,Zuul可以感知該服務器何時出現問題。這兩個指標,是故障和延遲的大致指標,當超過這兩個指標閾值的百分之一時,我們將通過限制流量,來降低服務器負載。
全局節流
另一種情況是Zuul本身出現問題。與上面情況相反,全局節流將影響Zuul后面所有后端服務器,而不是單個后端服務器,這種全局節流的影響,可能會給成員國帶來更大的問題。用于觸發全局限制的關鍵指標,是CPU利用率、并發請求和連接數量,當超出任何一個這些指標的閾值時,Zuul將積極地限制流量,以在系統恢復的同時,保持自身的正常運行。這一功能非常關鍵:如果Zuul出現故障,流量就不能傳送到我們的后端服務器,從而導致供應的全面中斷。
引入基于優先級的漸進式負載分流
一旦確定了優先級,我們就可以將其與我們的減負機制結合起來,從而極大地提高流媒體的可靠性。當我們處于困境時(即超過上述任何閾值)時,我們會從最低優先級開始,逐步丟棄流量。三次函數用于管理節流級別,如果情況變得非常非常糟糕,這一水平將觸及曲線的尖端,使其能夠節掉任何流量。
上圖是如何應用立方函數的一個示例。隨著過載百分比的增加(即節流閾值和最大容量之間的范圍),優先級閾值非常緩慢地落后于它:過載百分比35%,優先級閾值仍然在90左右。如果系統繼續降級,我們的過載百分比會在超過80%的情況下,優先級達到50,然后在95%的情況下最終達到10,以此類推。
鑒于相對較少的請求,會影響流媒體可用性,限制低優先級流量,可能會影響某些產品功能,但不會阻礙到人們點擊“播放”,觀看他們最愛的節目。通過添加漸進式的,基于優先級的負載分流,Zuul可以減少足夠的流量來穩定服務,而不會引起人們察覺。
應對重試風暴
當Zuul決定減少流量時,它會向設備發送信號,設備接收到信號會執行后退命令。Zuul通過指示設備可以執行的重試次數,以及可以在哪種時間窗口內執行這些重試命令,解決出現的問題。例如:
利用這種反壓機制,我們可以比過去更快地停止重試風暴。我們根據請求的優先級自動調整這兩個刻度盤,相比較低優先級的請求,具有較高優先級的請求會更積極地重試,這也增加了流媒體的可用性。
驗證哪些請求適合作業
為了驗證我們關于特定請求是否屬于非關鍵型、體驗降級型或關鍵型的分類假設,我們需要一種方法來測試,當用戶在該請求被阻止時的體驗。為此,我們利用了內部故障注入工具(FIT),并在Zuul中創建了一個故障注入點,允許我們根據提供的優先級,舍棄任何請求。這使我們能夠通過阻止特定設備,或成員的優先級范圍,來手動模擬減負體驗,讓我們了解哪些請求可以安全地減負,而不會影響用戶。
持續確保這些請求仍然適用作業
這里的一個目標,是通過丟棄那些預計不會影響用戶流媒體體驗的請求,來減輕相對較糟的用戶體驗。然而,Netflix變化很快,原本被認為不關鍵的請求,可能會出人意料地變得關鍵。此外,Netflix擁有各種各樣的客戶端設備、客戶端版本,以及與系統交互的方式,為了確保在這些場景中,限制非關鍵請求時不會給成員帶來麻煩,我們利用了我們的基礎設施實驗平臺CHAP。
該平臺允許我們進行A/B實驗,將少量產品用戶,分配給對照組或實驗組,45分鐘的時間,同時限制實驗組一系列的優先級。這使我們能夠捕獲各種實時使用案例,并衡量它們對回放體驗的影響。CHAP分析每個設備成員的KPI,以確定對照組和實驗組之間是否存在偏差。
在我們的第一個實驗中,我們在Android和IOS設備上都檢測到了低優先級請求的競爭情況,這會導致零星的播放錯誤。由于我們進行的是連續實驗,所以一旦初始實驗運行、并修復了錯誤,我們就安排它們繼續定期運行。這使得當數據再次出現異常時,我們能夠及早發現它,從而保持用戶流媒體的正常運作。
FIX前后的實驗數據回歸檢測
初嘗成果
2019年,在漸進式分流法到位前,Netflix流媒體服務經歷了一次中斷,導致相當大比例的成員,在一段時間內無法看視頻。2020年,在該方法實施部署幾天后,團隊開始看到這種解決方案的好處。Netflix也遇到過與2019年的服務中斷事件類似、并有著相同潛在影響的事件。與當時不同的是,Zuul的漸進式減負手段開始發揮作用,開始減流流量,直到服務處于健康狀態,而且完全不會影響視頻播放的功能。
下圖顯示了穩定的每秒流可用性指標流(SPS),而Zuul正在根據事件期間請求的優先級進行漸進式負載分流。
圖表中的不同顏色,表示被限制的優先級不同的請求。
就此,在基礎架構從系統故障中自我恢復時,會員們仍能順利地在Netflix上觀看他們最喜歡的節目。
未完待續
在未來的工作中,我們這支團隊正在研究怎樣擴展請求優先級在其他用例中的運用,比如設備和后端之間更好的重試策略、動態更改負載分流閾值、以紊亂測試為指導原則,調整請求優先級,以及其他將使Netflix更具彈性的領域。






