自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

月均活躍用戶達1.3億,B站高可用架構(gòu)實踐

開發(fā) 架構(gòu) 開發(fā)工具
流量洪峰下要做好高服務(wù)質(zhì)量的架構(gòu)是一件具備挑戰(zhàn)的事情,本文詳細闡述了從 Google SRE 的系統(tǒng)方法論以及實際業(yè)務(wù)的應(yīng)對過程中出發(fā),一些體系化的可用性設(shè)計。對我們了解系統(tǒng)的全貌、上下游的聯(lián)防有更進一步的幫助。

流量洪峰下要做好高服務(wù)質(zhì)量的架構(gòu)是一件具備挑戰(zhàn)的事情,本文詳細闡述了從 Google SRE 的系統(tǒng)方法論以及實際業(yè)務(wù)的應(yīng)對過程中出發(fā),一些體系化的可用性設(shè)計。對我們了解系統(tǒng)的全貌、上下游的聯(lián)防有更進一步的幫助。

[[324088]]

本文來自公眾號云加社區(qū)(ID:QcloudCommunity)

負載均衡

負載均衡具體分成兩個方向,一個是前端負載均衡,另一個是數(shù)據(jù)中心內(nèi)部的負載均衡。

前端負載均衡方面,一般而言用戶流量訪問層面主要依據(jù) DNS,希望做到最小化用戶請求延遲。

將用戶流量最優(yōu)地分布在多個網(wǎng)絡(luò)鏈路上、多個數(shù)據(jù)中心、多臺服務(wù)器上,通過動態(tài) CDN 的方案達到最小延遲。

以上圖為例,用戶流量會先流入 BFE 的前端接入層,第一層的 BFE 實際上起到一個路由的作用,盡可能選擇跟接入節(jié)點比較近的一個機房,用來加速用戶請求。

然后通過 API 網(wǎng)關(guān)轉(zhuǎn)發(fā)到下游的服務(wù)層,可能是內(nèi)部的一些微服務(wù)或者業(yè)務(wù)的聚合層等,最終構(gòu)成一個完整的流量模式。

基于此,前端服務(wù)器的負載均衡主要考慮幾個邏輯:

  • 盡量選擇最近節(jié)點
  • 基于帶寬策略調(diào)度選擇 API 進入機房
  • 基于可用服務(wù)容量平衡流量

數(shù)據(jù)中心內(nèi)部的負載均衡方面,理想情況下會像上圖右邊顯示那樣,最忙和最不忙的節(jié)點所消耗的 CPU 相差幅度較小。

但如果負載均衡沒做好,情況可能就像上圖左邊一樣相差甚遠。由此可能導(dǎo)致資源調(diào)度、編排的困難,無法合理分配容器資源。

因此,數(shù)據(jù)中心內(nèi)部負載均衡主要考慮:

  • 均衡流量分發(fā)
  • 可靠識別異常節(jié)點
  • scale-out,增加同質(zhì)節(jié)點以擴容
  • 減少錯誤,提高可用性

我們此前通過同質(zhì)節(jié)點來擴容就發(fā)現(xiàn),內(nèi)網(wǎng)服務(wù)出現(xiàn) CPU 占用率過高的異常,通過排查發(fā)現(xiàn)背后 RPC 點到點通信間的 Health Check 成本過高,產(chǎn)生了一些問題。

另外一方面,底層的服務(wù)如果只有單套集群,當出現(xiàn)抖動的時候故障面會比較大,因此需要引入多集群來解決問題。

通過實現(xiàn) Client 到 Backend 的子集連接,我們做到了將后端平均分配給客戶端,同時可以處理節(jié)點變更,持續(xù)不斷均衡連接,避免大幅變動。

多集群下,則需要考慮集群遷移的運維成本,同時集群之間業(yè)務(wù)的數(shù)據(jù)存在較小的交集。

回到 CPU 忙時、閑時占用率過大的問題,我們會發(fā)現(xiàn)這背后跟負載均衡算法有關(guān)。

第一個問題:對于每一個 QPS,實際上就是每一個 query、查詢、API 請求,它們的成本是不同的。

節(jié)點與節(jié)點之間差異非常大,即便你做了均衡的流量分發(fā),但是從負載的角度來看,實際上還是不均勻的。

第二個問題:存在物理機環(huán)境上的差異。因為我們通常都是分年采購服務(wù)器,新買的服務(wù)器通常主頻 CPU 會更強一些,所以服務(wù)器本質(zhì)上很難做到強同質(zhì)。

基于此,參考 JSQ(最閑輪訓(xùn))負載均衡算法帶來的問題,發(fā)現(xiàn)缺乏的是服務(wù)端全局視圖,因此我們的目標需要綜合考慮負載和可用性。

我們參考了《The power of two choices in randomized load balancing》的思路,使用 the choice-of-2 算法,隨機選取的兩個節(jié)點進行打分,選擇更優(yōu)的節(jié)點:

  • 選擇 Backend:CPU,client:health、inflight、latency 作為指標,使用一個簡單的線性方程進行打分。
  • 對新啟動的節(jié)點使用常量懲罰值(penalty),以及使用探針方式最小化放量,進行預(yù)熱。
  • 打分比較低的節(jié)點,避免進入“永久黑名單”而無法恢復(fù),使用統(tǒng)計衰減的方式,讓節(jié)點指標逐漸恢復(fù)到初始狀態(tài)(即默認值)。

通過優(yōu)化負載均衡算法以后,我們做到了比較好的收益。

限流

避免過載,是負載均衡的一個重要目標。隨著壓力增加,無論負載均衡策略如何高效,系統(tǒng)某個部分總會過載。

我們優(yōu)先考慮優(yōu)雅降級,返回低質(zhì)量的結(jié)果,提供有損服務(wù)。在最差的情況,妥善的限流來保證服務(wù)本身穩(wěn)定。

限流這塊,我們認為主要關(guān)注以下幾點:

  • 針對 QPS 的限制,帶來請求成本不同、靜態(tài)閾值難以配置的問題。
  • 根據(jù) API 的重要性,按照優(yōu)先級丟棄。
  • 給每個用戶設(shè)置限制,全局過載發(fā)生時候,針對某些“異常”進行控制非常關(guān)鍵。
  • 拒絕請求也需要成本。
  • 每個服務(wù)都配置限流帶來的運維成本。

在限流策略上,我們首先采用的是分布式限流。我們通過實現(xiàn)一個 quota-server,用于給 Backend 針對每個 Client 進行控制,即 Backend 需要請求 quota-server 獲取 Quota。

這樣做的好處是減少請求 Server 的頻次,獲取完以后直接本地消費。算法層面使用最大最小公平算法,解決某個大消耗者導(dǎo)致的饑餓。

在客戶端側(cè),當出現(xiàn)某個用戶超過資源配額時,后端任務(wù)會快速拒絕請求,返回“配額不足”的錯誤。

有可能后端忙著不停發(fā)送拒絕請求,導(dǎo)致過載和依賴的資源出現(xiàn)大量錯誤,處于對下游的保護兩種狀況,我們選擇在 Client 側(cè)直接進行流量,而不發(fā)送到網(wǎng)絡(luò)層。

我們在 Google SRE 里學(xué)到了一個有意思的公式,max(0, (requests- K*accepts) / (requests + 1))。

通過這種公式,我們可以讓 Client 直接發(fā)送請求,一旦超過限制,按照概率進行截流。

在過載保護方面,核心思路就是在服務(wù)過載時,丟棄一定的流量,保證系統(tǒng)臨近過載時的峰值流量,以求自保護。

常見的做法有基于 CPU、內(nèi)存使用量來進行流量丟棄;使用隊列進行管理;可控延遲算法:CoDel 等。

簡單來說,當我們的 CPU 達到 80% 的時候,這個時候可以認為它接近過載,如果這個時候的吞吐達到 100,瞬時值的請求是 110,我就可以丟掉這 10 個流量。

這種情況下服務(wù)就可以進行自保護,我們基于這樣的思路最終實現(xiàn)了一個過載保護的算法。

我們使用 CPU 的滑動均值(CPU>800 )作為啟發(fā)閾值,一旦觸發(fā)就進入到過載保護階段。

算法為:(MaxPass*AvgRT)<InFlight

限流效果生效后,CPU 會在臨界值(800)附近抖動,如果不使用冷卻時間,那么一個短時間的 CPU 下降就可能導(dǎo)致大量請求被放行,嚴重時會打滿 CPU。

在冷卻時間后,重新判斷閾值(CPU>800 ),是否持續(xù)進入過載保護。

重試

流量的走向,一般會從 BFE 到 LB(負載均衡)然后經(jīng)過 API 網(wǎng)關(guān)再到 BFF、微服務(wù)最后到數(shù)據(jù)庫,這個過程要經(jīng)過非常多層。

在我們的日常工作中,當請求返回錯誤,對于 Backend 部分節(jié)點過載的情況下,我們應(yīng)該怎么做?

  • 首先我們需要限制重試的次數(shù),以及基于重試分布的策略。
  • 其次,我們只應(yīng)該在失敗層進行重試,當重試仍然失敗時,我們需要全局約定錯誤碼,避免級聯(lián)重試。
  • 此外,我們需要使用隨機化、指數(shù)型遞增的充實周期,這里可以參考 Exponential Backoff 和 Jitter。
  • 最后,我們需要設(shè)定重試速率指標,用于診斷故障。

而在客戶端側(cè),則需要做限速。因為用戶總是會頻繁嘗試去訪問一個不可達的服務(wù),因此客戶端需要限制請求頻次,可以通過接口級別的 error_details,掛載到每個 API 返回的響應(yīng)里。

超時

我們之前講過,大部分的故障都是因為超時控制不合理導(dǎo)致的。首當其沖的是高并發(fā)下的高延遲服務(wù),導(dǎo)致 Client 堆積,引發(fā)線程阻塞,此時上游流量不斷涌入,最終引發(fā)故障。

所以,從本質(zhì)上理解超時它實際就是一種 Fail Fast 的策略,就是讓我們的請求盡可能消耗,類似這種堆積的請求基本上就是丟棄掉或者消耗掉。

另一個方面,當上游超時已經(jīng)返回給用戶后,下游可能還在執(zhí)行,這就會引發(fā)資源浪費的問題。

再一個問題,當我們對下游服務(wù)進行調(diào)優(yōu)時,到底如何配置超時,默認值策略應(yīng)該如何設(shè)定?

生產(chǎn)環(huán)境下經(jīng)常會遇到手抖或者錯誤配置導(dǎo)致配置失敗、出現(xiàn)故障的問題。所以我們最好是在框架層面做一些防御性的編程,讓它盡可能讓取在一個合理的區(qū)間內(nèi)。

進程內(nèi)的超時控制,關(guān)鍵要看一個請求在每個階段(網(wǎng)絡(luò)請求)開始前,檢查是否還有足夠的剩余來處理請求。

另外,在進程內(nèi)可能會有一些邏輯計算,我們通常認為這種時間比較少,所以一般不做控制。

現(xiàn)在很多 RPC 框架都在做跨進程超時控制,為什么要做這個?跨進程超時控制同樣可以參考進程內(nèi)的超時控制思路,通過 RPC 的源數(shù)據(jù)傳遞,把它帶到下游服務(wù),然后利用配額繼續(xù)傳遞,最終使得上下游鏈路不超過一秒。

應(yīng)對連鎖故障

結(jié)合我們上面講到的四個方面,應(yīng)對連鎖故障,我們有以下幾大關(guān)鍵點需要考慮。

第一,我們需要盡可能避免過載。因為節(jié)點一個接一個掛了的話,最終服務(wù)會雪崩,有可能機群都會跟著宕掉,所以我們才提到要做自保護。

第二,我們通過一些手段去做限流。它可以讓某一個 Client 對服務(wù)出現(xiàn)高流量并發(fā)請求時進行管控,這樣的話服務(wù)也不容易死。

另外,當我們無法正常服務(wù)的時候,還可以做有損服務(wù),犧牲掉一些非核心服務(wù)去保證關(guān)鍵服務(wù),做到優(yōu)雅降級。

第三,在重試策略上,在微服務(wù)內(nèi)盡可能做退避,盡可能要考慮到重試放大的流量倍數(shù)對下游的沖擊。

另外還要考慮在移動端用戶用不了某個功能的情況下,通常會頻繁刷新頁面,這樣產(chǎn)生的流量沖擊,我們在移動端也要進行配合來做流控。

第四,超時控制強調(diào)兩個點,進程內(nèi)的超時和跨進程的傳遞。最終它的超時鏈路是由最上層的一個節(jié)點決定的,只要這一點做到了,我覺得大概率是不太可能出現(xiàn)連鎖故障的。

第五,變更管理。我們通常情況下發(fā)布都是因為一些變更導(dǎo)致的,所以說我們在變更管理上還是要加強,變更流程中出現(xiàn)的破壞性行為應(yīng)該要進行懲罰,盡管是對事不對人,但是還是要進行懲罰以引起重視。

第六,極限壓測和故障演練。在做壓測的時候,可能壓到報錯就停了。我建議最好是在報錯的情況下,仍然要繼續(xù)加壓,看你的服務(wù)到底是一個什么表現(xiàn)?它能不能在過載的情況下提供服務(wù)?

在上了過載保護算法以后,繼續(xù)加壓,積極拒絕,然后結(jié)合熔斷的話,可以產(chǎn)生一個立體的保護效果。

經(jīng)常做故障演練可以產(chǎn)生一個品控手冊,每個人都可以學(xué)習,經(jīng)常演練不容易慌亂,當在生產(chǎn)環(huán)境中真的出現(xiàn)問題時也可以快速投入解決。

第七,考慮擴容、重啟、消除有害流量。

如上圖所示的參考,就是對以上幾個策略的經(jīng)典補充,也是解決各種服務(wù)問題的玄學(xué)。

作者:毛劍

簡介:bilibili 技術(shù)總監(jiān),騰訊云最具價值專家(TVP)。負責 bilibili 數(shù)據(jù)平臺部,擁有近十年的服務(wù)端研發(fā)經(jīng)驗。擅長高性能、高可用的服務(wù)端研發(fā),熟悉 Go、Java、C 等語言。在 B 站參與了,從巨石架構(gòu)到微服務(wù)的完整轉(zhuǎn)型,包含微服務(wù)治理、微服務(wù)可用性設(shè)計,微服務(wù)數(shù)據(jù)一致性設(shè)計,微服務(wù)中間件,微服務(wù)監(jiān)控,微服務(wù)日志收集,微服務(wù)負載均衡,和微服務(wù) RPC 框架開發(fā)等。開源業(yè)內(nèi)比較有影響力的項目:https://github.com/Terry-Mao/goim,分布式 IM 長連接廣播服務(wù);https://github.com/Terry-Mao/bfs,分布式小文件存儲。

編輯:陶家龍

出處:轉(zhuǎn)載自微信公眾號云加社區(qū)(ID:QcloudCommunity),本文是 B 站技術(shù)總監(jiān)毛劍老師在「云加社區(qū)沙龍 online」的分享整理。

 

責任編輯:武曉燕 來源: 云加社區(qū)
相關(guān)推薦

2022-07-05 15:08:52

機房架構(gòu)

2024-08-13 12:54:20

2022-01-11 21:06:45

微信企業(yè)微信移動應(yīng)用

2018-09-10 08:27:18

登錄Auth0架構(gòu)

2018-09-27 18:34:08

架構(gòu)Auth0

2023-05-30 07:27:45

高可用架構(gòu)流量

2021-08-02 16:28:46

網(wǎng)信辦IPv6IPv4

2019-12-24 09:30:59

蘇寧高可用高并發(fā)

2017-10-27 14:52:31

互聯(lián)網(wǎng)高可用架構(gòu)高可用

2011-07-27 15:28:39

Opera Mini瀏覽器

2017-11-08 09:32:05

2021-07-15 07:23:48

高可用熱搜B站

2023-08-31 07:30:09

AIGC代碼監(jiān)測

2022-09-15 15:18:23

計算實踐

2024-02-28 07:50:36

大數(shù)據(jù)標簽系統(tǒng)AB 實驗

2019-10-11 10:52:42

Web架構(gòu)MongoDB

2015-12-16 11:27:52

Google高可用架構(gòu)

2024-11-11 16:29:54

負載均衡器系統(tǒng)

2023-04-04 12:38:50

GPT機器人LLM

2020-08-28 15:48:52

IPv6LTE終端網(wǎng)絡(luò)基礎(chǔ)
點贊
收藏

51CTO技術(shù)棧公眾號