導讀
家人團聚共賞春晚,已經成為國人歡度春節必不可少的慶祝方式。如今,愛奇藝春晚直播,成為千千萬萬家庭同享這份歡樂的新途徑。根據以往的統計資料,春晚期間愛奇藝的訪問量是平時的數倍甚至是數十倍,不亞於12306春節搶票的“盛況”,這也給系統帶來了前所未有的訪問壓力。我們在2019年直播中加入了個性化節目和互動元素,介面複雜度更高,團隊重點任務則是保障直播間資訊、直播互動等後端直播內容流暢響應。除了春晚直播,像明星演唱會、綜藝節目等大型直播也是我們重點服務物件。簡而言之我們團隊提供的是大型直播業務API服務,我們簡稱“QLive”。
大型直播往往帶來的就是大流量和高併發,而我們的“QLive”也經受住了多次業務洪峰的洗禮和考驗,下面是我們團隊經歷過的一些大型直播。
一、整體架構
在春晚這種高併發的場景下,對“QLive”伸縮擴容和高可用具有較高的要求。而在網際網路分散式架構設計中,為了提高系統併發能力主要有兩種方法論:
方法 | 實施策略 | 優點 | 缺點 |
垂直擴充套件 | 提升單機併發處理能力 | 節省機器 採購成本 | 單機效能 有極限 |
水平擴充 | 增加對應業務機或者儲存的伺服器數量 | 機器資源足夠的話能線性提升併發能力 | 有一定的機器採購成本 |
我們綜合考慮了這兩種方法,設計了多級快取策略提升介面響應速度同時也提高了單機承載併發的上限,在應用層部署了雙機房從而線性增加了整個服務的併發承載能力。經過線上壓測,“QLive”目前承載40萬+的qps。
接下來具體看下“QLive”的整體架構,整體上分成三層:
1. 接入層(業務中臺):
主要扮演的角色是負載均衡、降級、業務封裝、避免複雜性擴散,而且考慮到接入層位置的特殊性(物理上最接近使用者),我們部署了外網多機房,主要有以下兩個明顯的作用:
· 讓不同運營商的使用者以最短路徑接入系統。
· 避免由於部分主幹網路故障導致的單點故障。
2.應用層(雙機房架構):
實現了機房隔離、服務隔離、熱點隔離等策略,提高了叢集可用性和水平擴充套件的靈活性。
3.基礎服務層:
運維平臺
· 監控報警:通過分鐘級報警感知、多維度監控圖表做到業務提前預警和故障快速定位。
· CMDB:資源管理、依賴管理、流程規範。
· 釋出系統:管理程式碼上線、審計、回滾等功能。
資料中心
· 計算中心:基於Quartz的分散式任務排程系統,非同步處理資料量大或者耗時長的業務。
· Trace鏈路日誌:Agent無侵入式部署、快速定位程式碼效能問題、可追溯的效能資料。
· 資料中心:前端PingBack、收集外網使用者故障形成閉環、實時生成資料包表。
二、接入層—業務中臺
接入層主要有兩部分組成:閘道器服務、業務中臺。為了防止系統過載,在接入閘道器服務中加入了熔斷降級的策略,保證在極端情況下部分核心服務是可用的。
首先我們需要明確熔斷和降級這兩種概念:服務熔斷一般是某個下游服務故障引起的;服務降級是整體服務壓力過大需要保護核心業務採取的一些降級策略。
服務熔斷:
在閘道器服務中經常會對後端不同api介面做服務聚合,比如A服務 -> B服務 -> C服務 ,如果C服務出現問題,那麼在呼叫C服務之前需要做熔斷。而在設計熔斷器的時候主要實現了以下三個狀態:
狀態 | 具體策略 |
Closed | 熔斷器關閉狀態,如果服務呼叫失敗,則使失敗次數加1,失敗次數到了一定閾值或者一定比例,則啟動熔斷機制。 |
Open | 熔斷器開啟狀態,在該狀態下會對出錯的服務請求立即返回錯誤響應,同時設計了一個時鐘選項,預設的時鐘達到了一定時間(這個時間一般設定成平均故障處理時間,也就是MTTR),到了這個時間,進入半熔斷狀態。 |
Half-Open | 允許定量的服務請求,如果呼叫在一定比例上都成功了則認為已恢復,關閉熔斷器(重置失敗次數),否則開啟熔斷器。 |
服務降級:
我們主要使用了自動開關降級、人工開關降級這兩種策略。
· 自動開關降級:根據系統負載、整體超時率、失敗次數等指標選擇對次要功能(比如視訊播放次數)做降級,降級後的處理方案有返回預設值、兜底資料、快取等方案。
· 人工開關降級:通過監控報警發現線上一些服務存在問題,這個時候需要暫時將有問題的服務摘掉,比如某個快取節點異常讀取不到資料 ;如果發現某些寫的服務呼叫量太大,如果不是強實時性,同步寫的方式可以改成非同步緩解儲存壓力。
三、應用層—雙機房架構
雙機房的主要技術挑戰是機房間的延時、資料同步的問題。
1.機房延時問題:A城市的兩個核心機房延時大概在1ms內,但是A城市到B城市則可能有近30ms的延時,如果應用依賴的服務都跨機房訪問那麼效能會慘不忍睹。
2.資料同步問題:如果MySQL、Redis等資料儲存需要做不同機房的資料同步,如果有幾十毫秒的延時,整個資料同步是非常大的挑戰。
3.解決方案:
· 同城機房部署,機房延時可以忽略不計。
· 機房隔離,服務和服務之間,服務和資源之間使用智慧DNS連線,儘量保證服務不跨機房呼叫。
四、應用層—多級快取
為了提高單機併發承載能力,我們設計了多級快取架構,最終線上服務端核心介面平均響應耗時在10ms內。
· 主要技術挑戰:不同快取之間資料一致性問題。
· 快取中介軟體:一級快取local cache+二級分散式快取Redis。
· 解決資料一致性的問題:利用Redis Pub/Sub(釋出/訂閱)的特性以及設計合理的Redis key 來避免以上問題。每個業務機上有個後臺執行緒訂閱redis訊息,如果計算中心更新Redis成功會publish訊息,後臺執行緒收到Redis的訊息會更新當前本地快取,保證每次更新資料時使用者看到的資料都是相同的。
· 代理層快取:使用者訪問量很多時候是無法預期的,機器數量不變的情況下,如何效能最大化是我們經常思考的問題。上圖可以看出主要併發壓力來自業務WebServer,直播節目有個特性,直播節目資訊、流地址不會發生變化,通常只有在開播狀態變更和直播結束時間延後會更改直播資訊。在實際實踐過程中發現,可以將核心節目介面功能上移到Nginx層,只有在配置中心加入快取頭的節目才會進行動態檔案的快取,保證快取量控制極少的量,這樣可以利用Nginx快取檔案優勢,結合自身業務系統的特點,讓靜態快取的靈活性和效率都能得到保障。
五、基礎服務層—監控大屏
監控大屏主要分資料採集和圖表展示,資料採集流程如下:
· flume Agent收集採集Nginx的訪問日誌。
· 多個Agent資料匯聚到同一個Agent。
· Kafka作為訊息通道將資料儲存到Hive。
· 通過大資料平臺(babel)將不同緯度的資料彙總到業務mysql資料庫中。
· 監控大屏最終展示彙總資料。
六、展望
以上是愛奇藝直播團隊在大型直播場景下應對大流量高併發的一些思考,整個系統也經過了多次大型直播的考驗,始終保持在低故障率,可用性做到了99.9999%。除了應對高流量,如何降低訪問鏈路、加快業務方對接、直播元件化也是目前探索的方向。