B站S11破億直播線上穩定性保障祕籍——TakinTalks演講實錄

語言: CN / TW / HK

《英雄聯盟》S11全球總決賽·決賽中國戰隊奪冠,賽事直播盛況空前,觀賽人數破億。B站作為英雄聯盟2021全球總決賽直播獨家版權方不僅在整個比賽過程中保證了直播整體總體執行的平穩,還抗住了超預期的流量。

如此大型的直播活動,B站究竟是如何保障系統穩定的呢?

以下內容整理自TakinTalks·live直播活動中B站呂帆老師的精彩分享,若想檢視精彩回放戳👉https://news.shulie.io/?p=4279(文末附課件下載方式)

講師介紹

呂帆

嗶哩嗶哩直播B&C端架構組leader

個人簡介: 畢業於華中科技大學,碩士。曾就職於美團點評,螞蟻金服等公司,擁有豐富的服務端研發開發架構經驗,對於高可用高併發系統設計,系統穩定性保障,服務治理,單元化部署,網路協議,加解密,網際網路常見業務(直播,營銷,開發平臺,交易等)等方面較多實踐經驗。

為了保障這場活動的穩定性,B站投入了近4個月的時間,上百人蔘與其中,從7月份就開始了相關籌備工作。總體規劃包含Web端、移動端、服務端、運維、直播流、採購等多型別事務,同時涵蓋了公司8個以上的團隊、10餘項大項執行專案。為了給到使用者最佳的視聽互動體驗,反覆打磨每一個使用場景、進行多輪壓測、混沌測試、預設降級策略、限流策略、設定預案/SOP、臨場保障等,從而保證該賽事直播的順利進行。接下來我將從這裡面挑一些重點來跟大家分享。

一、前置優化

前置優化有3塊主要內容:服務規範化、制定指南針指標、日誌的梳理與告警。

1.服務規範化

一共梳理了16條規範,其中有7條是需要大家重點關注的,可以簡單分享一下其中幾點內容。

服務之間的呼叫,服務呼叫儲存層(Mysql、Redis)需要設定合理的超時,這個點沒有經歷過高併發高可用場景的話可能會不太理解。我們之前經歷過這樣一個事件,當時有個服務呼叫資料庫,我們的超時設計不合理過長了,結果因為資料庫抖動,我們整個服務都卡著等超時最後整個就掛掉了。這就是為什麼我們會單獨列這條規範了。

呼叫外部服務或者儲存層如果重試的必要,需要有限的合理的重試,這也是從我們之前的經歷中總結出來的規範。之前有個開發同學特別有心,想著Redis大部分是讀比較多,為了讓藉口的效能提高,他做了一個重試,重試次數設定了5次。其實想法是好的,但遇到極端情況就出現問題了,當時這個Redis叢集有一個節點抖動了於是產生了大量的重試,這個節點的流量一下增加了5倍,結果就打掛了。

2.制定指南針指標

指南針指標是服務對業務的核心價值體現,指南針指標同時也體現服務的健康與否 ,指南針指標的波動,一定意味著業務出現波動,業務出現問題,指南針指標一定異常。所以只要制定了正確的指南針指標,並加以監控和告警就能及時反饋系統問題。

3.日誌的梳理與告警

出現問題大家的第一反應基本都是去看日誌/監控,但就如同下圖,有寫告警它並沒有告訴你影響這麼樣、發生了什麼事情,那這就是無效的告警,無法幫助開發進行定位為題治標不治本。 為了讓日誌和告警發揮它原本的作用,我們對日誌進行了分級並提出了規範要求,必須要體現報錯的原因以及具體的解決方案。同時我們喧雜在可能出現故障的地方打日誌設定告警,這樣就能快速準確定位問題和解決了。 文末附課件下載方式

二、場景梳理

對於多數研發來說,關注的僅是自身服務是否可用,但是由服務串聯成的場景才是實際使用者感知的使用過程。定義場景能幫助我們更好的識別場景、理解場景、利於保障,是保障的基礎。我們將場景的定義羅列了5項,其中場景級別、場景互動(包含上下游)、相關介面是比較重要的梳理項。

以B站的直播首頁為例,大家可以看看我們針對一個具體的場景會梳理哪些內容。基於這一套梳理流程,我們一共梳理了40+的實際場景。

三、流量預估

系統的壓力來自於海量使用者每一個行為的流量。梳理好場景後,我們需要從入口梳理出每個場景的流量,也就是這個場景需要承受的QPS,然後再具體到這個場景涉及的每個介面的QPS,如進入直播房間場景:

從上圖,我們總結出進房場景涉及的服務和介面以及對應的QPS。這裡有必要說一下QPS的預估方法,主要有兩種:

  • 歷史流量演算法:根據當前&歷年活動流量,計算整體業務體量同比增量模型。 此演算法比較適用於一些老的場景,老的介面。
  • 流量轉化演算法(GMV\DAU\訂單量):一般以業務預估總量 (GMV\DAU\訂單量)為輸入,根據日常業務量-流量轉化模型(比如經典漏斗模型)換算得到對應子域業務體量評估。 此演算法比較適用於一些新的場景,新的介面,特別是本次活動新增的。

四、壓測

保障系統穩定性最大的難題在於容量規劃,而容量規劃最大的難題在於準確評估系統的實際承載能力。通過壓測可以評估系統的實際承載能力。另外,高併發時,壓測可以檢測到一些在流量比較低的時候發現不了的問題。這次我們共進行了三輪壓測,每輪壓測都會執行多次:

第一輪:先不擴容,壓出系統的極限,找出瓶頸和優化點 第二輪:等系統優化和業務需求做完,擴容後,按照S11預計流量壓測 第三輪:驗證,迴歸,查漏補缺 這裡有總結一些壓測的常見問題以及背後的原因,僅供參考。

文末附課件下載方式

經過多輪的壓測,我們也總結出了壓測時應該注意的事項:

壓測前:

  • 確定場景下所有要壓測的介面,如果有的介面不太容易壓測(比如會產生髒資料)暫時先不壓測,但是後期需要做預案(比如如何保障,出了問題怎麼辦,降級方案是什麼)
  • 開啟介面限流
  • 壓測資訊周知到你依賴的服務的負責人,如果涉及Mysql,Tidb,Redis,MQ等同樣需要周知到對應負責人
  • 如果多個場景對同一個服務都依賴,那多個場景需要一起壓測

壓測中:

  • 開始要緩慢施壓且控制壓測時間(比如1分鐘),以防止出現問題。
  • 緊盯各項監控(服務的監控,Redis,Mysql,Tidb,MQ等),如有異常,立即停止壓測
  • 遇到日誌報錯增多,立即停止壓測
  • 遇到介面耗時明顯增加,立即停止壓測
  • 資源(伺服器,Redis,Mysql,Tidb,Databus等)逼近極限,需停止壓測
  • 多輪壓測,步步提升QPS
  • 保證壓測流量均衡
  • 記錄壓測過程中不同壓測QPS下各項資源(伺服器,Redis,Mysql,Tidb,MQ等)壓力情況,以供後續分析

壓測後:

  • 檢視各項監控,服務是否健康,QPS是否正常,保證服務沒有問題
  • 如果有臨時資料,是否要清除

五、混沌工程

雖然壓測已經做過,但這只是在系統正常執行情況下的表現。真實情況中,線上系統經常會出現各式各樣的異常,那麼我們能否主動找出系統中的脆弱環節,提前做加固、防範呢?另外保障的核心還是在於人,所以我們還需要鍛鍊參與保障的同學,讓他們能夠臨危不亂,冷靜的解決遇到的問題,為此我們引入了混沌工程。 本次混沌實驗的目的:通過故障注入,驗收證明全鏈路的高可用性, 包括監控、告警、定位、恢復體系。主要聚焦在以下幾個最常見的故障場景去做演練:

  • DB不可用/不穩定(超時,抖動等)
  • Cache叢集不可用/不穩定(超時,抖動等)
  • 依賴的RPC服務不可用/不穩定(超時,抖動等)
  • 網路抖動
  • 宕機

以下為本次我們的推進過程:

  • 梳理整個系統的部署架構圖,如下所示: 根據部署架構圖,可以清楚地看到服務所依賴的各種資源的關係,這樣就可以根據部署架構圖在每一個呼叫鏈路上設定故障點。
  • 設定故障點 根據部署架構圖,可以設定DB不可用/不穩定,Cache叢集不可用/不穩定,依賴的RPC服務不可用/不穩定,機器宕機,網路抖動等故障
  • 故障演練 演練由測試同學在任意時間觸發任意故障,然後記錄開發同學可否1分鐘發現故障,五分鐘定位故障,十分鐘解決故障。同時記錄故障演練的過程,參考如下:

文末附課件下載方式

根據以往經驗,故障演練可以分至少兩輪,第一輪對所有故障點進行一場演練,演練完之後進行系統優化,第二輪可以採取”考試“模式對故障點進行抽檢。

六、線上問題處理

前面介紹的都是如何保障系統不要出現問題,那萬一真的出現問題了該怎麼辦呢?總結一下線上問題的處理手段一共有5種:限流、降級、熔斷、擴容和Hotfix(改程式碼上線)。

1.預案與sop

要想在大型活動的高併發流量場景下,快速對線上緊急事故進行響應處理,僅僅依賴值班同學臨場發揮是遠遠不夠的。爭分奪秒的情況下,無法給處理人員留有充足的策略思考空間,而錯誤的處理決策,往往會導致更為失控、嚴重的業務與系統影響。因此,要想在現場快速而正確地響應問題,值班同學需要做的是選擇題,而不是陳述題。而選項的構成,便是我們的預案。保障S11順利播出,我們對每個場景整理了一套處理問題的“標準作業程式”,也就是所謂的SOP。每一個SOP大致有下面四點:

  1. 我們需要確定每個場景的模組出現問題的表現;
  2. 確定問題出現了,我們要確認該怎麼做;
  3. 誰來做;
  4. 怎麼做。

2.降級

降級目的是削弱非核心服務資源佔用,保證業務核心服務穩定性。降級策略有很多方面需要思考與落地,在這裡總結一下經常用到降級策略。

  • 頁面降級:非核心頁面模組,佔用緊張資源,關停該頁面,減少訪問;
  • 服務降級:將功能分類,分為核心服務與非核心服務,將非核心服務進行關停;
  • 依賴降級:將依賴服務梳理分類,保證核心依賴的穩定,將非核心進行降級關停;
  • 讀寫降級:將直接讀寫資料庫切換為讀寫快取;對於快取依舊可以進行備份冗餘;
  • 延遲降級:頁面的非同步載入策略;資料寫入非同步訊息佇列等。

降級的實現方式,大體分為兩種,一種是自動降級,一種是主動降級。

  1. 自動降級:
  • 一般可以通過程式碼層面處理,比如呼叫介面返回了err,對於golang,我們可以判斷err是否為nil,如果不為nil可以進行降級處理,如果是Java,出現Exception,可以在Catch中處理。
  • 也可以通過熔斷器進行自動降級,但是需要考慮好熔斷的閾值。
  1. 手動降級:一般通過開關處理,開關的實現有很多種,比如配置中心。 瞭解了降級方法之後,我們還需要清楚不是所有服務都能降級,也不是等到故障發生了以後,才去選擇或者確定哪些服務可以降級。故障的降級策略一定要提前規劃與思考。 系統或者服務需要分為核心和非核心。核心服務是我們力保不能有任何問題的主流程服務 P0;非核心服務,又可以根據重要性進行再次分層。可以劃分為 P1、P2、P3 服務:
  • P0 服務為主服務,是力保穩定性的物件,他們掛了整個業務也就崩潰了;

  • P1 服務為與緊密主服務相關,但可以後續非同步補償來操作的服務,比如說,結算流水,訂單統計;

  • P2服務與主服務有點相關,但關閉了對主服務任何業務邏輯沒有影響,比如說,訂單評價,商品推薦等;

  • P3服務與主服務沒有相關,關閉之後對主服務沒有任何影響,比如說,廣告推薦,使用者喜好,評論瀏覽等。

在梳理服務等級的時候,需要注意 2-8 原則,也就是 20% 為核心系統,80% 為非核心繫統。因此我們主要精力要放在20% 的核心繫統。在本次S11穩定性保障中,我們做了一定的降級策略如:

  • 直播首屏場景,正常情況下,會走演算法推薦,但是如果演算法推薦出了問題,通過開關切到簡單排序規則
  • 使用者心跳場景,正常情況下上報間隔是一分鐘上報一次,如果出現資源問題,可以在配置中心,修改上報間隔到5分鐘

3.限流

大型微服務架構中的任何服務節點,不管怎麼優化,怎麼拓展,都會有能力上限。如果達到能力上限,系統服務崩潰的可能性就會增加,這種情況也很容易造成整個微服務應用的雪崩效應。 當伺服器的壓力劇增的情況下,為了保證服務不被拖垮,對一些流量採取拒絕或者降級的策略,以此來保證核心服務的正常運轉。這是一種有損的技術手段。 因為限流是一種有損的技術手段,而且平時使用的情況不多,所以如何決策是否要做出限流操作,在S11的活動中我們做了如下定義: 大前提:流量的突然增加,或者依賴的資源(比如儲存層)有異常(可能是流量突增導致也有可能是儲存抖動導致)且對業務有損,短時間沒有有效的恢復手段,系統無法承受當前流量,且認為限流可以緩解當前情況 舉個例子:

  • 儲存資源(Mysql,Redis等)問題:比如Mysql等資源出現不可用情況(比如,cpu跑滿,大量超時或者大量慢sql)且沒有恢復跡象
  • 流量突增:在某些情況下,你認為流量導致的問題,比如流量突增
  • 外部介面耗時增加:如果系統呼叫外部介面,外部介面突然出現耗時增加,導致系統伺服器的cpu跑滿,導致系統不可用

限流不是目的,只是解決當前緊急情況的一個手段,並且對系統是有損的,所以要持續關注限流的效果和對系統的影響,並且及時解除。 本次S11,我們分別對核心介面做了:

  • SLB限流配置
  • Ekango限流配置
  • WAF單IP限速

臨場保障主要涉及值班人員安排和現場保障與事故記錄兩個方面,這邊就不展開了。

寫在最後

今年B站還會有S12賽季直播活動,所以我們現在也是陸陸續續開始相關的保障工作了。與之前相比,今年新增了多機房部署,這個也比較常見,就是某個機房出現問題了就可以快速把流量切換到另一個機房。B站的直播主要是讀流量,所以我們做的是讀流量的多機房部署,整體還是比較容易的。此外我們還在探索單元化和多活方向的保障手段,到時候可以再跟大家分享分享這部分的內容。

檢視精彩回放戳👉https://news.shulie.io/?p=4279

直播Q&A整理https://news.shulie.io/?p=4312

掃碼關注公眾號,回覆【B站】關鍵詞獲取講師PPT

在這裡插入圖片描述