千萬級使用者直播APP——服務端結構設計和思考
摘要: 在2016杭州雲棲大會的“開發者技術峰會”上,來自一下科技的技術副總裁張華偉給大家解密了一直播千萬級使用者服務端架構設計和成長曆程。
一直播產品是一下科技今年五月份剛上線的產品。得益於與微博的深度合作,以及與小咖秀、秒拍共同運營,一直播開始時就有一個很高的起點,短短半年內,達到同時線上使用者百萬級規模。在2016杭州雲棲大會的“開發者技術峰會”上,來自一下科技的技術副總裁張華偉給大家解密了一直播千萬級使用者服務端架構設計和成長曆程。
以下內容根據演講PPT及現場分享整理。
直播行業是今年最為火爆的行業,作為新興的產品形態,直播產品最大的特點是:快。推流速度足夠快,主播通過移動端快速推流,使用者能快速看到直播場景,延遲需要足夠低,而且移動端型別十分複雜、種類繁多,這是一個很大的挑戰;首幀載入速度要足夠快,使用者開啟直播頁面時,能立即觀看畫面;支付也需要足夠快,使用者給主播送禮物時,保證直播時的互動效果;錄製、轉碼、儲存都需要足夠快。
那麼一直播是如何在短短半年內應對這些如此之快的要求呢?下面從業務結構、快取、互動、排程四個方面為你揭開祕密。
業務結構——叢集+模組化
一個優秀的網際網路專案架構至少應該做到兩點:第一點模組化拆分;第二點資源分層。將一個複雜的系統拆分成N個小系統,之後再對小系統進行功能優化。如上圖所示,一直播平臺架構的最前端是安全防護接入層,用於系統的安全防護;此後是URL路由,將流量從入口通過負載均衡按照使用者請求URL下發到不同的模組上,再導流到後端不同的叢集上,從源頭上進行分流;URL路由之後是介面層,將後端的服務、功能模組的介面進行整合,之再後提供給前端使用者。
下面具體看一下每個模組的功能與結構。
路由排程
目前,一直播平臺中採用二級域名+分層目錄路由的方式進行URL分層,如member層、評論層、直播層等一級目錄直接下發到不同叢集上;二級目錄做成對外的介面,如API、OpenAPI、Web層,再將其劃分到內部介面、外介面或H5、PC上;第三層目錄是真正處理的業務邏輯。
這樣分層處理之後,後期的分叢集優化就變得十分簡單。
模組化拆分
前端進行URL分層之後,後端需要按照業務功能進行模組拆分,將複雜的功能拆解,例如將使用者系統拆解成一個獨立的使用者服務,再將使用者服務拆分成使用者註冊、使用者中心、關注關係等。模組化拆解之後,單模組資源共享,無交叉影響;同時,還可以將核心業務與非核心業務分開,核心業務放在核心資源池內,在突發流量到來時,可以優先保證核心業務的可用性,非核心業務進行降級或者關閉處理;此外,訊息佇列非同步持久化,如圖中所示的使用者、快取的後端持久化都是相互獨立的,保證訊息響應速度。
資源分層治理
接下來看一下資源分層治理,整個系統按照功能模組拆分後,各種資源分層之後,後期的資源治理就變得十分簡單。在接入層,蒐集全部日誌資源,對所有的請求做分析,便於後期監控、資料分析等處理;在介面層,使用者請求進來之後,下發到不同的介面叢集上,介面叢集對後端的服務進行組合封裝。介面層承載了大量的壓力,在預知大的活動發生前,可以在該層人工或系統自動擴容一批機器,例如在趙本山直播前,在該層將機器的數目增加一倍。服務層是真正的業務處理層,它包含了業務處理、快取、資料持久化。服務層下側是快取和持久化層,之所以將二者分開,是因為快取在網際網路架構中的重要性不言而喻,在突發流量到來時,快取至少可以承載系統80%-90%的壓力。
資料庫
一直播架構中按照模組、功能劃分資料庫,不同的資料庫再分配到不同的物理機上,並非整個專案共用資料庫。由於絕大數應用讀遠遠大於寫,因此,在該場景下可以對資料庫進行讀寫分離,如Master-Slave、MySQL等方式;同時對資料庫進行水平、垂直拆分。
快取——多級快取之演變
基本的快取模型如上圖所示,服務層直接呼叫後端的快取叢集,但在一直播架構中增加了本地快取。當某一大明星的直播開始時,在極短的時間內大量的粉絲會同時湧進一個直播間,此時主播的熱度是非常高的,如果將全部請求都匯入後端叢集,勢必給後端叢集帶來非常大的壓力。當大量資料在短期內變化不是特別大時,可以在前端的業務層上本地快取(可以採用Memcached、Reids等方式),通過在本地快取3-5秒就可以承受80%-90%系統壓力,瞬間化解後端快取叢集的壓力。
後端的快取叢集的常規設計有兩種:
- 第一種是將大資料通過HASH模式分拆到後端不同機器上,加大可承載的資料量,這種方式的缺點是:當無法進行本地快取只能採用遠端叢集時,如果過HASH模式將某Key下發到後端的某個節點上,會瞬間給該節點帶來較大的壓力,一旦該節點掛掉,前端的介面層和業務層會出現卡頓現象,進而導致整個系統癱瘓為了應對這種情況;
- 第二種方式是目前一直播架構中採用的方式,在前端掛一層HASH模式,通過HASH將Key分佈開,後端通過主從模式,做成一主多從的模式,進而解決熱點key讀取量大的難題。
在快取中,還有一點需要注意的是:重點資料單獨佈署。如果對所有的叢集全部按照第二種方式搭建,成本勢必很高。由於大量的主播訪問量並不是很高,如果進行主從部署時也會導致資源的大量浪費,因此對於大明星、網紅等重點主播的Key可採取單獨部署的方式,以節約資本。
互動——百萬線上聊天室搭建
談到移動直播,互動必然是繞不開的話題。移動直播聊天室和傳統的聊天室不同,他主要具有以下幾個特點:
- 使用者集中在熱點直播間
- 熱點直播訊息量巨大
- 訊息實時性強
- 使用者進出直播間隨機性大
劉燁和本山大叔的直播,單個直播間有百萬級別的使用者實時線上聊天、送禮互動。
那麼支撐如此龐大使用者的聊天室架構是如何設計的呢?如上圖所示,一直播的聊天室架構主要分為接入層、路由層,其中接入層又分為連線保持層和業務邏輯處理層。通過在接入層保持使用者的連線;路由層進行訊息中轉;業務層對接入層傳入的訊息進行處理。該架構需要保障可用性、擴充套件性和低延遲,首先接入層需要擴充套件,因為接入層需要掛在全平臺線上的使用者,所有訊息的下發都是通過接入層處理;在路由層,訊息量反而減小。
上圖是平臺訊息的流轉圖。客戶端上行訊息之後,通過接入層接入業務邏輯處理;由於整個直播平臺是構建在阿里雲ECS上,而ECS單機掛載的使用者量有限,因此訊息經業務邏輯處理之後需要進入本地佇列,將請求平滑後進行業務處理,平滑的過程取決於後端的處理執行緒,根據平臺規模動態調整執行緒數量,保持訊息佇列中訊息數目最少,從而保證訊息到達的及時性。
業務邏輯層對訊息進行處理後,將訊息轉發給後端的路由層;路由層根據訊息的訊號記錄,通過路由層的索引規則發給其他路由節點;其它路由節點下發給自身掛載的接入節點;接入節點收到訊息之後,同樣進入訊息佇列,執行緒處理方式同上,對訊息進行判斷,如果是單方向的訊息直接轉發,多方向的訊息迴圈轉發給節點使用者。
對於大型直播間,由於移動端資源有限,對所有訊息全部轉發是不可能實現的,因此需要對訊息進行限流。流控原則第一種方式式根據訊息型別,如果將使用者評論全部轉發給客戶端,則會出現滾屏現象,導致資訊無法識別,這時需要對訊息按時間維度進行管控(一分鐘內下發定量訊息);第二種方式是按照線上人數,將線上人數分割槽(幾萬個使用者為一區),各分割槽間訊息互通;第三種方式根據使用者特徵,對級別較低的使用者和剛註冊的使用者的發言進行適當遮蔽。
排程——推流+播放
排程主要包括推流排程和播放排程。移動端和傳統秀場直播不同,傳統秀場通過PC端進行推流,移動端的網速、效能相比於PC端都存在一定的差距,因此移動端的推流受限於使用者的裝置和地理位置的不確定性,例如在一直播平臺上,明星主播或網路紅人的位置非常隨機,有可能在非洲或者在巴西奧運會現場亦或是偏僻的山區,在這些場景下如果本地排程出現偏差,推流的質量就會非常差。
目前一直播平臺在推流和播放的排程方面採用的是第三方的CDN。如上圖所示,使用者需要推流,首先到排程中心獲取離他最近的推流節點;使用者將流上傳到推流節點後,該節點將流分發到流控中心;流控中心再將流分發到內部的CDN網路上,內部的CDN網路再將該流下發到各個節點上。當用戶需要播放直播時,首先到最近的排程節點上獲取最近的播放節點,獲取播放節點之後播放即可。目前播放協議上行支援RTMP;下行時Http/flv和M3U8效果更好,在H5上一般採用M3U8,移動端、PC端採用Http/flv。