作者 / Manuel Correa,Arthur Gonigberg,Daniel West
譯者 / Alpha
原文鏈接/https://netflixtechblog.com/keeping-netflix-reliable-using-prioritized-load-shedding-6cc827b02f94
對世界各地的司機(jī)來說,堵車是最令人沮喪的經(jīng)歷之一。每個人都緩慢得像是在爬行一樣,有時是因為出現(xiàn)了一個小問題,有時則是毫無理由的擁堵。作為Netflix的工程師,我們一直在不斷評估如何重新設(shè)計流量管理框架。如果我們知道每個人行程的緊迫性,就可以有針對性地為他們選擇路線,而不是讓大家做無謂的等待,這么做的結(jié)果會如何呢?
在Netflix的工程設(shè)計中,我們的動力是確保Netflix可以在您需要的時候及時出現(xiàn)。然而,就在去年,我們的系統(tǒng)還很容易受到人們所說的的“交通擁堵”的影響;我們有開關(guān)斷路器,但沒有循序漸進(jìn)的方式來減輕負(fù)載。為了改善會員的播放體驗,我們引入了基于優(yōu)先級的漸進(jìn)式減載法。
下面的動畫展示了當(dāng)后端根據(jù)優(yōu)先級限制流量時,觀眾體驗到的Netflix性能。當(dāng)較低優(yōu)先級的請求被限制時,整個播放體驗完整流暢,觀眾可以盡情享受觀看的內(nèi)容。接下來讓我們深入研究一下我們是如何做到這一點的。

觸發(fā)失敗的誘因有很多,比如客戶端行為不當(dāng)引發(fā)的重試風(fēng)暴、后臺服務(wù)器規(guī)模不足、部署不當(dāng)、網(wǎng)絡(luò)故障或云提供商的問題等等。任何上述原因都可能瞬即給系統(tǒng)造成巨大的載荷,在以前,這些例子中的每一個都會使我們的會員無法播放視頻。為了防止此類突發(fā)事件的發(fā)生,我們開始著手實現(xiàn)以下目標(biāo),使Netflix的服務(wù)更具彈性:
- 跨設(shè)備(移動、瀏覽器和電視)持續(xù)確定請求的優(yōu)先級
- 根據(jù)優(yōu)先級逐步限制請求
- 通過對特定優(yōu)先級的請求進(jìn)行紊亂測試(Chaos Testing)(有意的故障輸入)來驗證假設(shè)
我們設(shè)想的,包含優(yōu)先級節(jié)流和紊亂測試的最終架構(gòu),如下所示。

具有優(yōu)先級節(jié)流和紊亂測試的高級播放端架構(gòu)
構(gòu)建請求分類
我們決定聚焦于三個維度來對請求流量進(jìn)行分類:吞吐量、功能性和重要性。根據(jù)這些特征,流量被分為以下幾類:
- 非關(guān)鍵型請求:該類型流量不影響播放或會員體驗,日志和后臺請求就屬于此類流量。此類請求通常有較高的吞吐量,是系統(tǒng)負(fù)載來源中占據(jù)比例較大的部分。
- 體驗降級型請求:該類型流量影響會員體驗,但不影響播放功能。此類請求流量常用于以下功能:停止和暫停標(biāo)記、播放器中的語言選擇、觀看歷史記錄等。
- 關(guān)鍵型請求:流量影響播放功能。如果請求失敗,會員在點擊播放時會看到一條錯誤消息。
API網(wǎng)關(guān)服務(wù)(Zuul)根據(jù)請求的屬性,將其分為非關(guān)鍵型請求、體驗降級型請求和關(guān)鍵型請求,并根據(jù)每個請求的單獨特征,計算它們從1到100之間的優(yōu)先級分?jǐn)?shù)。計算是任務(wù)開始的第一步,以便在其余關(guān)于請求的工作流程中來使用。
大多數(shù)情況下,請求的工作流在不考慮請求優(yōu)先級的情況下,也可以正常運(yùn)行。然而,就像任何服務(wù)器一樣,有時我們會遇到這樣的情況:我們的兩個后端中有一個遇到了麻煩,或者Zuul本身也遇到了麻煩。當(dāng)這種情況發(fā)生時,具有更高優(yōu)先級的請求將得到優(yōu)先處理。優(yōu)先級較高的請求將得到服務(wù),而優(yōu)先級較低的請求不會被接待。它的執(zhí)行,類似于具有動態(tài)優(yōu)先級閾值的優(yōu)先級隊列,允許Zuul丟棄優(yōu)先級低于當(dāng)前閾值的請求。
尋找最佳的流量控制點
在請求的整個生命周期中,Zuul有兩個時間點可以執(zhí)行負(fù)載分流:當(dāng)它將請求,路由到特定的后端服務(wù)器時(服務(wù)器節(jié)流),或者在初始請求處理時,這會影響所有后端服務(wù)(全局節(jié)流)。
服務(wù)器節(jié)流
通過監(jiān)控錯誤率和對后端服務(wù)的并發(fā)請求,Zuul可以感知該服務(wù)器何時出現(xiàn)問題。這兩個指標(biāo),是故障和延遲的大致指標(biāo),當(dāng)超過這兩個指標(biāo)閾值的百分之一時,我們將通過限制流量,來降低服務(wù)器負(fù)載。
全局節(jié)流
另一種情況是Zuul本身出現(xiàn)問題。與上面情況相反,全局節(jié)流將影響Zuul后面所有后端服務(wù)器,而不是單個后端服務(wù)器,這種全局節(jié)流的影響,可能會給成員國帶來更大的問題。用于觸發(fā)全局限制的關(guān)鍵指標(biāo),是CPU利用率、并發(fā)請求和連接數(shù)量,當(dāng)超出任何一個這些指標(biāo)的閾值時,Zuul將積極地限制流量,以在系統(tǒng)恢復(fù)的同時,保持自身的正常運(yùn)行。這一功能非常關(guān)鍵:如果Zuul出現(xiàn)故障,流量就不能傳送到我們的后端服務(wù)器,從而導(dǎo)致供應(yīng)的全面中斷。
引入基于優(yōu)先級的漸進(jìn)式負(fù)載分流
一旦確定了優(yōu)先級,我們就可以將其與我們的減負(fù)機(jī)制結(jié)合起來,從而極大地提高流媒體的可靠性。當(dāng)我們處于困境時(即超過上述任何閾值)時,我們會從最低優(yōu)先級開始,逐步丟棄流量。三次函數(shù)用于管理節(jié)流級別,如果情況變得非常非常糟糕,這一水平將觸及曲線的尖端,使其能夠節(jié)掉任何流量。

上圖是如何應(yīng)用立方函數(shù)的一個示例。隨著過載百分比的增加(即節(jié)流閾值和最大容量之間的范圍),優(yōu)先級閾值非常緩慢地落后于它:過載百分比35%,優(yōu)先級閾值仍然在90左右。如果系統(tǒng)繼續(xù)降級,我們的過載百分比會在超過80%的情況下,優(yōu)先級達(dá)到50,然后在95%的情況下最終達(dá)到10,以此類推。
鑒于相對較少的請求,會影響流媒體可用性,限制低優(yōu)先級流量,可能會影響某些產(chǎn)品功能,但不會阻礙到人們點擊“播放”,觀看他們最愛的節(jié)目。通過添加漸進(jìn)式的,基于優(yōu)先級的負(fù)載分流,Zuul可以減少足夠的流量來穩(wěn)定服務(wù),而不會引起人們察覺。
應(yīng)對重試風(fēng)暴
當(dāng)Zuul決定減少流量時,它會向設(shè)備發(fā)送信號,設(shè)備接收到信號會執(zhí)行后退命令。Zuul通過指示設(shè)備可以執(zhí)行的重試次數(shù),以及可以在哪種時間窗口內(nèi)執(zhí)行這些重試命令,解決出現(xiàn)的問題。例如:

利用這種反壓機(jī)制,我們可以比過去更快地停止重試風(fēng)暴。我們根據(jù)請求的優(yōu)先級自動調(diào)整這兩個刻度盤,相比較低優(yōu)先級的請求,具有較高優(yōu)先級的請求會更積極地重試,這也增加了流媒體的可用性。
驗證哪些請求適合作業(yè)
為了驗證我們關(guān)于特定請求是否屬于非關(guān)鍵型、體驗降級型或關(guān)鍵型的分類假設(shè),我們需要一種方法來測試,當(dāng)用戶在該請求被阻止時的體驗。為此,我們利用了內(nèi)部故障注入工具(FIT),并在Zuul中創(chuàng)建了一個故障注入點,允許我們根據(jù)提供的優(yōu)先級,舍棄任何請求。這使我們能夠通過阻止特定設(shè)備,或成員的優(yōu)先級范圍,來手動模擬減負(fù)體驗,讓我們了解哪些請求可以安全地減負(fù),而不會影響用戶。
持續(xù)確保這些請求仍然適用作業(yè)
這里的一個目標(biāo),是通過丟棄那些預(yù)計不會影響用戶流媒體體驗的請求,來減輕相對較糟的用戶體驗。然而,Netflix變化很快,原本被認(rèn)為不關(guān)鍵的請求,可能會出人意料地變得關(guān)鍵。此外,Netflix擁有各種各樣的客戶端設(shè)備、客戶端版本,以及與系統(tǒng)交互的方式,為了確保在這些場景中,限制非關(guān)鍵請求時不會給成員帶來麻煩,我們利用了我們的基礎(chǔ)設(shè)施實驗平臺CHAP。
該平臺允許我們進(jìn)行A/B實驗,將少量產(chǎn)品用戶,分配給對照組或?qū)嶒灲M,45分鐘的時間,同時限制實驗組一系列的優(yōu)先級。這使我們能夠捕獲各種實時使用案例,并衡量它們對回放體驗的影響。CHAP分析每個設(shè)備成員的KPI,以確定對照組和實驗組之間是否存在偏差。
在我們的第一個實驗中,我們在Android和IOS設(shè)備上都檢測到了低優(yōu)先級請求的競爭情況,這會導(dǎo)致零星的播放錯誤。由于我們進(jìn)行的是連續(xù)實驗,所以一旦初始實驗運(yùn)行、并修復(fù)了錯誤,我們就安排它們繼續(xù)定期運(yùn)行。這使得當(dāng)數(shù)據(jù)再次出現(xiàn)異常時,我們能夠及早發(fā)現(xiàn)它,從而保持用戶流媒體的正常運(yùn)作。

FIX前后的實驗數(shù)據(jù)回歸檢測
初嘗成果
2019年,在漸進(jìn)式分流法到位前,Netflix流媒體服務(wù)經(jīng)歷了一次中斷,導(dǎo)致相當(dāng)大比例的成員,在一段時間內(nèi)無法看視頻。2020年,在該方法實施部署幾天后,團(tuán)隊開始看到這種解決方案的好處。Netflix也遇到過與2019年的服務(wù)中斷事件類似、并有著相同潛在影響的事件。與當(dāng)時不同的是,Zuul的漸進(jìn)式減負(fù)手段開始發(fā)揮作用,開始減流流量,直到服務(wù)處于健康狀態(tài),而且完全不會影響視頻播放的功能。
下圖顯示了穩(wěn)定的每秒流可用性指標(biāo)流(SPS),而Zuul正在根據(jù)事件期間請求的優(yōu)先級進(jìn)行漸進(jìn)式負(fù)載分流。

圖表中的不同顏色,表示被限制的優(yōu)先級不同的請求。
就此,在基礎(chǔ)架構(gòu)從系統(tǒng)故障中自我恢復(fù)時,會員們?nèi)阅茼樌卦贜etflix上觀看他們最喜歡的節(jié)目。
未完待續(xù)
在未來的工作中,我們這支團(tuán)隊正在研究怎樣擴(kuò)展請求優(yōu)先級在其他用例中的運(yùn)用,比如設(shè)備和后端之間更好的重試策略、動態(tài)更改負(fù)載分流閾值、以紊亂測試為指導(dǎo)原則,調(diào)整請求優(yōu)先級,以及其他將使Netflix更具彈性的領(lǐng)域。