一直播産品是一下科技今年五月份剛上線的産品。得益于與微網誌的深度合作,以及與小咖秀、秒拍共同營運,一直播開始時就有一個很高的起點,短短半年内,達到同時線上使用者百萬級規模。在2016杭州雲栖大會的“開發者技術峰會”上,來自一下科技的技術副總裁張華偉給大家解密了一直播千萬級使用者服務端架構設計和成長曆程。
以下内容根據演講ppt及現場分享整理。
直播行業是今年最為火爆的行業,作為新興的産品形态,直播産品最大的特點是:快。推流速度足夠快,主播通過移動端快速推流,使用者能快速看到直播場景,延遲需要足夠低,而且移動端類型十分複雜、種類繁多,這是一個很大的挑戰;首幀加載速度要足夠快,使用者打開直播頁面時,能立即觀看畫面;支付也需要足夠快,使用者給主播送禮物時,保證直播時的互動效果;錄制、轉碼、存儲都需要足夠快。
那麼一直播是如何在短短半年内應對這些如此之快的要求呢?下面從<b>業務結構、緩存、互動、排程</b>四個方面為你揭開秘密。
業務結構——叢集+子產品化

一個優秀的網際網路項目架構至少應該做到兩點:第一點子產品化拆分;第二點資源分層。将一個複雜的系統拆分成n個小系統,之後再對小系統進行功能優化。如上圖所示,一直播平台架構的最前端是安全防護接入層,用于系統的安全防護;此後是url路由,将流量從入口通過負載均衡按照使用者請求url下發到不同的子產品上,再導流到後端不同的叢集上,從源頭上進行分流;url路由之後是接口層,将後端的服務、功能子產品的接口進行整合,之再後提供給前端使用者。
下面具體看一下每個子產品的功能與結構。
<b>路由排程</b><b></b>
目前,一直播平台中采用二級域名+分層目錄路由的方式進行url分層,如member層、評論層、直播層等一級目錄直接下發到不同叢集上;二級目錄做成對外的接口,如api、openapi、web層,再将其劃分到内部接口、外接口或h5、pc上;第三層目錄是真正處理的業務邏輯。
這樣分層處理之後,後期的分叢集優化就變得十分簡單。
<b>子產品化拆分</b><b></b>
前端進行url分層之後,後端需要按照業務功能進行子產品拆分,将複雜的功能拆解,例如将使用者系統拆解成一個獨立的使用者服務,再将使用者服務拆分成使用者注冊、使用者中心、關注關系等。子產品化拆解之後,單子產品資源共享,無交叉影響;同時,還可以将核心業務與非核心業務分開,核心業務放在核心資源池内,在突發流量到來時,可以優先保證核心業務的可用性,非核心業務進行降級或者關閉處理;此外,消息隊列異步持久化,如圖中所示的使用者、緩存的後端持久化都是互相獨立的,保證消息響應速度。
<b>資源分層治理</b><b></b>
接下來看一下資源分層治理,整個系統按照功能子產品拆分後,各種資源分層之後,後期的資源治理就變得十分簡單。在接入層,搜集全部日志資源,對所有的請求做分析,便于後期監控、資料分析等處理;在接口層,使用者請求進來之後,下發到不同的接口叢集上,接口叢集對後端的服務進行組合封裝。接口層承載了大量的壓力,在預知大的活動發生前,可以在該層人工或系統自動擴容一批機器,例如在趙本山直播前,在該層将機器的數目增加一倍。服務層是真正的業務處理層,它包含了業務處理、緩存、資料持久化。服務層下側是緩存和持久化層,之是以将二者分開,是因為緩存在網際網路架構中的重要性不言而喻,在突發流量到來時,緩存至少可以承載系統80%-90%的壓力。
<b>資料庫</b><b></b>
一直播架構中按照子產品、功能劃分資料庫,不同的資料庫再配置設定到不同的實體機上,并非整個項目共用資料庫。由于絕大數應用讀遠遠大于寫,是以,在該場景下可以對資料庫進行讀寫分離,如master-slave、mysql等方式;同時對資料庫進行水準、垂直拆分。
緩存——多級緩存之演變<b></b>
基本的緩存模型如上圖所示,服務層直接調用後端的緩存叢集,但在一直播架構中增加了本地緩存。當某一大明星的直播開始時,在極短的時間内大量的粉絲會同時湧進一個直播間,此時主播的熱度是非常高的,如果将全部請求都導入後端叢集,勢必給後端叢集帶來非常大的壓力。當大量資料在短期内變化不是特别大時,可以在前端的業務層上本地緩存(可以采用memcached、reids等方式),通過在本地緩存3-5秒就可以承受80%-90%系統壓力,瞬間化解後端緩存叢集的壓力。
後端的緩存叢集的正常設計有兩種:
第一種是将大資料通過hash模式分拆到後端不同機器上,加大可承載的資料量,這種方式的缺點是:當無法進行本地緩存隻能采用遠端叢集時,如果過hash模式将某key下發到後端的某個節點上,會瞬間給該節點帶來較大的壓力,一旦該節點挂掉,前端的接口層和業務層會出現卡頓現象,進而導緻整個系統癱瘓為了應對這種情況;
第二種方式是目前一直播架構中采用的方式,在前端挂一層hash模式,通過hash将key分布開,後端通過主從模式,做成一主多從的模式,進而解決熱點key讀取量大的難題。
在緩存中,<b>還有一點需要注意的是:重點資料單獨布署。</b>如果對所有的叢集全部按照第二種方式搭建,成本勢必很高。由于大量的主播通路量并不是很高,如果進行主從部署時也會導緻資源的大量浪費,是以對于大明星、網紅等重點主播的key可采取單獨部署的方式,以節約資本。
互動——百萬線上聊天室搭建<b></b>
談到移動直播,互動必然是繞不開的話題。移動直播聊天室和傳統的聊天室不同,他主要具有以下幾個特點:
使用者集中在熱點直播間
熱點直播消息量巨大
消息實時性強
使用者進出直播間随機性大
劉烨和本山大叔的直播,單個直播間有百萬級别的使用者實時線上聊天、送禮互動。
那麼支撐如此龐大使用者的聊天室架構是如何設計的呢?如上圖所示,一直播的聊天室架構主要分為接入層、路由層,其中接入層又分為連接配接保持層和業務邏輯處理層。通過在接入層保持使用者的連接配接;路由層進行消息中轉;業務層對接入層傳入的消息進行處理。該架構需要保障可用性、擴充性和低延遲,首先接入層需要擴充,因為接入層需要挂在全平台線上的使用者,所有消息的下發都是通過接入層處理;在路由層,消息量反而減小。
上圖是平台消息的流轉圖。用戶端上行消息之後,通過接入層接入業務邏輯處理;由于整個直播平台是建構在阿裡雲ecs上,而ecs單機挂載的使用者量有限,是以消息經業務邏輯處理之後需要進入本地隊列,将請求平滑後進行業務處理,平滑的過程取決于後端的處理線程,根據平台規模動态調整線程數量,保持消息隊列中消息數目最少,進而保證消息到達的及時性。
業務邏輯層對消息進行處理後,将消息轉發給後端的路由層;路由層根據消息的信号記錄,通過路由層的索引規則發給其他路由節點;其它路由節點下發給自身挂載的接入節點;接入節點收到消息之後,同樣進入消息隊列,線程處理方式同上,對消息進行判斷,如果是單方向的消息直接轉發,多方向的消息循環轉發給節點使用者。
對于大型直播間,由于移動端資源有限,對所有消息全部轉發是不可能實作的,是以需要對消息進行限流。流控原則第一種方式式根據消息類型,如果将使用者評論全部轉發給用戶端,則會出現滾屏現象,導緻資訊無法識别,這時需要對消息按時間次元進行管控(一分鐘内下發定量消息);第二種方式是按照線上人數,将線上人數分區(幾萬個使用者為一區),各分區間消息互通;第三種方式根據使用者特征,對級别較低的使用者和剛注冊的使用者的發言進行适當屏蔽。
排程——推流+播放<b></b>
排程主要包括推流排程和播放排程。移動端和傳統秀場直播不同,傳統秀場通過pc端進行推流,移動端的網速、性能相比于pc端都存在一定的差距,是以移動端的推流受限于使用者的裝置和地理位置的不确定性,例如在一直播平台上,明星主播或網絡紅人的位置非常随機,有可能在非洲或者在巴西奧運會現場亦或是偏僻的山區,在這些場景下如果本地排程出現偏差,推流的品質就會非常差。<b></b>
目前一直播平台在推流和播放的排程方面采用的是第三方的cdn。如上圖所示,使用者需要推流,首先到排程中心擷取離他最近的推流節點;使用者将流上傳到推流節點後,該節點将流分發到流控中心;流控中心再将流分發到内部的cdn網絡上,内部的cdn網絡再将該流下發到各個節點上。當使用者需要播放直播時,首先到最近的排程節點上擷取最近的播放節點,擷取播放節點之後播放即可。目前播放協定上行支援rtmp;下行時http/flv和m3u8效果更好,在h5上一般采用m3u8,移動端、pc端采用http/flv。