微博短視頻百萬級高可用、高并發(fā)架構(gòu)如何設(shè)計?
本文從設(shè)計及服務(wù)可用性方面,詳細解析了微博短視頻高可用、高并發(fā)架構(gòu)設(shè)計中的問題與解決方案。
今天與大家分享的是微博短視頻業(yè)務(wù)的高并發(fā)架構(gòu),具體內(nèi)容分為如下三個方面:
- 團隊介紹
- 微博視頻業(yè)務(wù)場景
- “微博故事”業(yè)務(wù)場景架構(gòu)設(shè)計
團隊介紹
我們是隸屬于微博研發(fā)部視頻平臺研發(fā)部門的技術(shù)團隊。平臺研發(fā)是微博的核心部門之一,包括大家熟知的微博視頻在內(nèi)的微博所有核心業(yè)務(wù)的基礎(chǔ)平臺架構(gòu)、用戶關(guān)系體系等都依賴微博平臺研發(fā)部門的技術(shù)支持。
我們的團隊主要負責(zé)與視頻相關(guān)的上層業(yè)務(wù)也就是視頻微博、“微博故事”以及短視頻和直播,其中直播包括常規(guī)的直播與直播答題等新玩法。
同時我們還負責(zé)底層視頻平臺的架構(gòu)搭建,包括文件平臺、轉(zhuǎn)碼平臺、配置調(diào)度中心與媒體庫。
我們致力于用技術(shù)幫助微博從容應(yīng)對每天***的視頻增量與其背后多項業(yè)務(wù)的多種定制化需求。
微博視頻業(yè)務(wù)場景
我們的業(yè)務(wù)場景主要是應(yīng)對熱門事件的流量暴漲,例如明星緋聞、爆炸性新聞等勢必會讓流量在短時間內(nèi)急劇增長的事件。
如何從架構(gòu)上保證流量暴漲時整體平臺的穩(wěn)定性?如果只是簡單地通過調(diào)整服務(wù)器規(guī)模解決,流量較小時過多的服務(wù)器冗余帶來成本的浪費,流量暴漲時過少的服務(wù)器又令平臺服務(wù)處于崩潰的邊緣。
比較特別的是,我們面臨的問題與諸如“雙十一”這種在某一確定時間段內(nèi)流量的可預(yù)見式高并發(fā)有著本質(zhì)的不同,我們面臨的流量暴漲是不可預(yù)見的。因此通過哪些技術(shù)手段來妥善解決以上問題,將是接下探討的重點。
以上是基于微博的過去已經(jīng)公開數(shù)據(jù)量級,非近期內(nèi)部數(shù)據(jù)。微博視頻是一個多業(yè)務(wù)接入的綜合平臺,你可以在微博上看見現(xiàn)在市面上的各種玩法。
這就導(dǎo)致我們即將面臨的并不是某個垂直業(yè)務(wù)領(lǐng)域的***,而是一個構(gòu)建在龐大體量下的綜合性***,這就導(dǎo)致現(xiàn)有的通用技術(shù)框架無法妥善解決我們所面臨的難題。
因為一些開源方案無法順利通過技術(shù)壓測,所以我們只能在開源方案的基礎(chǔ)上進行自研與優(yōu)化才能得到符合微博應(yīng)用場景需求的技術(shù)解決方案。
微博的短視頻業(yè)務(wù)被稱為“微博故事”,上圖展示的是“微博故事”的展現(xiàn)形態(tài)。這是一個布置在微博首頁一級入口上的模塊,主要展示的是用戶關(guān)注的人所上傳的 15 秒內(nèi)的短視頻。
我們希望強調(diào)其“即時互動”的屬性,視頻只有 24 小時的有效展示時間。不同用戶的視頻按照時間軸在上方排序,多個視頻可依次觀看、評論、點贊等。
“微博故事”業(yè)務(wù)場景架構(gòu)設(shè)計
微服務(wù)架構(gòu)
上圖展示的是這項業(yè)務(wù)的微服務(wù)架構(gòu):在接口層我們混布了 Web API 與內(nèi)部的 RPC 請求。
在這里我們并未集成具有實際意義的門面層,而接下來的服務(wù)層集成了許多微服務(wù),每個微服務(wù)集中在一個垂直功能上并可對外提供接口,這里的門面層主要作用是聚合一些微服務(wù)并對外提供綜合性接口。
除此之外還有一些依賴服務(wù)例如用戶關(guān)注、也需要依賴于其他部門的 RPC 服務(wù);***的存儲層則是集成了 Cache 與 db 的標(biāo)準(zhǔn)方案。
技術(shù)挑戰(zhàn)
有人曾問到:微博短視頻業(yè)務(wù)的高并發(fā)有多高?假設(shè)我關(guān)注了 500 名好友,如果有好友發(fā)布一個視頻就會在“微博故事”頭像列表上顯示一個彩圈用以提示我去觀看。
如果我想知道自己所有關(guān)注的 500 個人所發(fā)的視頻內(nèi)容,假設(shè)首頁每秒刷新十萬次,那么需要每秒鐘五千萬的 QPS。
除此之外我們還需要確定視頻是否過期、視頻發(fā)送順序等,實際的資源層讀取量將遠遠高于五千萬。
方案比較
在構(gòu)建解決方案時我們思考:可以借鑒微博之前的 Feed 解決方案,我們不會進行無意義的重復(fù)性工作與思考。
即使短視頻與 Feed 都具有首頁刷新與關(guān)注人發(fā)布消息聚合的特點,但以用戶列表為形式,強調(diào)進度續(xù)播與即時互動的短視頻和以內(nèi)容列表為形式,強調(diào)無閱讀狀態(tài)與***保存的微博具有本質(zhì)的區(qū)別。
面對一般的 Feed 應(yīng)用場景可以使用以下兩種模型:
- Feed 推模型
- Feed 拉模型
①Feed 推模型
Feed 推模型是指將用戶上傳發(fā)布的內(nèi)容推送至每一位粉絲,這種方案具有很大的弊端。由于用戶尚未達成一定規(guī)模,早期的微博以 Feed 推模型為主導(dǎo)。
而現(xiàn)在一個大 V 用戶的粉絲數(shù)量普遍都是***別,如果依舊使用 Feed 推模型則意味著千萬量級的內(nèi)容推送,在難以保證千萬份推送一致性的情況下,勢必會為服務(wù)器帶來巨大壓力。
微博的業(yè)務(wù)強調(diào)的就是強時效性下的內(nèi)容一致性,我們需要確保熱點事件推送的瞬時與一致。
除了從技術(shù)層面很難確保***別內(nèi)容推送的時效性與一致性,由于用戶上線狀態(tài)的不統(tǒng)一,為離線的用戶推送強時效性的內(nèi)容無疑是對服務(wù)器等資源的巨大浪費,為了避免以上麻煩我們必須改變思路。
②Feed 拉模型
Feed 拉模型:拉取關(guān)注的人并實時查詢狀態(tài)及內(nèi)容。綜合微博的龐大用戶體量、數(shù)據(jù)寫入開銷與確保一致性三方面,我們決定選擇 Feed 拉模型。
如何通過 Feed 拉模型應(yīng)對如此規(guī)模龐大的 QPS?首先我們采用了分布式緩存架構(gòu),在緩存層集成了數(shù)據(jù)分片并將緩存通過哈希算法合理分片,之后再把緩存去切片化并進行存取。
分布式緩存架構(gòu)
其次我們使用了獨有的多級緩存方案也就是 L1、 Master 、Slave 三層緩存方案。
L1 是一個熱度極高容量極小的緩存,我們稱其為“極熱緩存”,其特點是便于橫向擴展。
假設(shè) L1 只有 200MB 緩存,我們使用 LRU 算法通過熱度分析把訪問最熱的數(shù)據(jù)存儲在 L1 中;之后的 Master 與 Slave 的緩存空間則是 4GB、6GB,比 L1 大很多倍。
因為微博的流量比較集中于熱點事件中某幾位明星或某個新聞,小容量的 L1 可進行快速擴容;在發(fā)生熱門事件時利用云的彈性自動擴容從而分擔(dān)熱點事件短時間激增的流量壓力。
由于自動擴容時 L1 僅占用每臺緩存中很小的空間,擴容的速度就會非??欤ㄟ^這種手動或自動的瞬間彈性擴容來確保服務(wù)器穩(wěn)定承受熱點事件背后的數(shù)據(jù)激增量。
第二層的 Master 與 Slave 具有比 L1 大好多倍的緩存空間,主要用于防止數(shù)據(jù)冷穿。
雖然 L1 主要承擔(dān)的是熱點數(shù)據(jù),但卻無法確保一些短時間內(nèi)不熱但在某個時間段熱度突然高漲所帶來的流量短時間爆發(fā)時服務(wù)器的穩(wěn)定性。
HA 多機房部署
而 Master 與 Slave 作為 L1 的邏輯分組可有效防止數(shù)據(jù)過冷,在這里我們采用的是 HA 多機房部署。
例如圖中的的兩臺 IDC,我們稱左邊為 IDC-A,右邊為 IDC-B。緩存層的 Master 與 Slave 是主從同步的關(guān)系,雙機房的緩存互相主從同步。
這里的“互相主從同步”是指 IDC-A 的 MC 與 IDC-B 的 MC 之間進行雙向同步互為主從。
因為在進行雙機房部署時需要均衡兩個機房的流量負載,在緩存層需要使用 LRU 算法進行熱度分析。
如果我們將流量分為兩份并傳輸至兩個機房,通過每個機房的 IRU 算法得到的熱度信息有一定失真。
如果我們在緩存層做相互同步后每個機房的 MC 都是一個全量的熱度算法,那么兩個機房的 L1 基本可實現(xiàn)同步計算得出的熱度信息一定是準(zhǔn)確的,只有保證熱度信息的準(zhǔn)確無誤才能從容應(yīng)對流量激增與整個系統(tǒng)的高可用性。
在這里需要強調(diào)的是,實際上我們在選型上使用的是 MC 而未使用 Redis。
MC 對于純簡單數(shù)據(jù) Key,Value 的抗量遠大于 Redis;MC 采用預(yù)分配內(nèi)存的形式放置 Key,Value,也就是把內(nèi)存分成若干組相同數(shù)據(jù)區(qū)域,實際上就是若干個數(shù)組。
這種特殊結(jié)構(gòu)使其在數(shù)據(jù)定位數(shù)組尋址與讀寫上的速度非???這種結(jié)構(gòu)的缺點是:一旦緩存的數(shù)據(jù)出現(xiàn)變動就會出現(xiàn)即使內(nèi)存留有空余但數(shù)據(jù)依舊無法存儲的現(xiàn)象。
由于這種問題的存在,MC 不適用于存儲變動大、Value 跨度大、業(yè)務(wù)多變的數(shù)據(jù)。
而 Redis 作為單線程方案,一致性更好,但在超大規(guī)模簡單 Key,Value 讀取上速度比 MC 是要差很多的。
除了上述方案之外,我們還采用了彈性擴縮容。實際應(yīng)用中,基于成本的考量我們無法部署大量的服務(wù)器,于是我們采用了自研的 DCP 彈性擴縮容平臺。
首先,我們的自有機房有一些共享機器資源可在特殊情況下動態(tài)彈性擴充以應(yīng)對增加的流量壓力。
當(dāng)然,這部分機器的性能是有限的,當(dāng)數(shù)據(jù)量超過一定閾值后我們就會接入阿里云并利用我們與阿里云的混合云 DCP 方式構(gòu)建一層彈性軟平臺用于自動擴容承擔(dān)流量壓力。
除了彈性擴容我們同時也采用了定時擴容的邏輯,在每天晚高峰時段進行擴縮容從而確保整體服務(wù)的穩(wěn)定性。之所以這么做,主要是為了在保證用戶體驗的前提下盡可能節(jié)約成本。
需要強調(diào)的是,擴容對速度的要求十分嚴(yán)格。只有擴容的速度越快,流量峰值來臨時可承受的數(shù)據(jù)量越大,才能確保整體服務(wù)的高可用,因而我們也在努力優(yōu)化擴容的速度。
我們的 DCP 平臺上也有晚高峰固定時段擴縮容與突發(fā)流量臨時擴縮容,通過如流量監(jiān)控等的自動化容量評估來判斷服務(wù)器荷載,并通過自動化任務(wù)調(diào)度妥善解決突發(fā)流量對服務(wù)器的影響。
微服務(wù)熔斷機制
當(dāng)然,為了保證服務(wù)器整體的健康與穩(wěn)定,我們也在其中集成了微服務(wù)熔斷機制,其原理類似于家用電表中的保險絲,可在過載的情況下迅速自動熔斷。
系統(tǒng)會定期進行自我評估并確定每個服務(wù)的***荷載,假設(shè)將熔斷值定為 3000QPS,那么當(dāng) QPS 超過 3000、超時或異常時服務(wù)即會迅速熔斷并關(guān)閉,從而確保其他資源的安全穩(wěn)定。
通過這種框架級、細粒度的自動降級機制,系統(tǒng)失敗隔離能力可被有效提高,避免了雪崩式的鏈?zhǔn)藉礄C事件的發(fā)生。在熔斷的同時,自動擴容也會同步運行。
熔斷之后系統(tǒng)會不斷更新服務(wù)流量荷載,一旦擴容完成或者服務(wù)還能繼續(xù)承受流量即可重新恢復(fù)工作,這種熔斷機制同樣也是為服務(wù)器擴容爭取時間。