1. 程式人生 > >TOP100summit:【分享實錄-QQ空間】10億級直播背後的技術優化

TOP100summit:【分享實錄-QQ空間】10億級直播背後的技術優化

rac rtmp d3d 占比 sha 壓縮 off 特殊 取數據

本篇文章內容來自2016年TOP100summit QQ空間客戶端研發總監王輝的案例分享。
編輯:Cynthia

王輝:騰訊SNG社交平臺部研發總監、騰訊QQ空間移動客戶端技術負責人高級工程師。09年起負責QQ空間技術研發,經歷從Web時代到移動客戶端技術的轉變,在Web、移動終端上都有不錯的技術積累。

導讀:移動互聯網飛速發展,2016年,社交網絡對視頻技術的應用得到爆發式的增長,短視頻、視頻直播、視頻濾鏡、視頻人臉動效、音樂、K歌、變聲、連麥等功能陸續在產品中上線,如何在快速上線功能的同時,保證穩定流暢的體驗,成為挑戰。
主要面臨的挑戰如下:
1、復雜的網絡環境下,如何保證視頻播放的成功率,如何保證直播的流暢度,減少卡頓?

2、體驗上,如何保證快速流暢的播放體驗,如何實現直播秒開,即點即播?
3、性能上,直播中濾鏡、美容、人臉動效,效果全開,如何保證主播端的性能?
4、億級海量並發用戶情況下,如何更好的保障質量,柔性帶寬的策略如何做到極致?
本案例圍繞上述挑戰進行,揭秘騰訊QQ空間團隊在挑戰中的一些優化嘗試。

一、案例介紹

QQ空間目前是國內最大的SNS社區,日高峰上傳5億張圖片,播放10億個視頻,6.3億用戶在這裏分享生活,留住感動,其中主流人群正是95後的年輕人。
也正因為是年輕人,且年輕人是生活方式轉變的主要推動力,不滿足於現在圖片+視頻傳統的分享方式,他們希望通過直播的方式讓你“現在、立刻、馬上”看到我。這就是內容消費的升級,同時伴隨著手機硬件的升級、流量費用的下降,於是手機直播變為可能。

而我們的直播產品定位也是基於目標用戶生活的內容,外加社交的傳播力量,有別於現在主流的網絡+遊戲直播的模式。
帶來的好處是:用戶創造的內容更多元化,更貼近生活,更能在好友間產生共鳴和傳播;
帶來的問題是:我們要兼容的移動終端也是海量的,性能問題是我們重點關註的內容。

在以上背景下,我們開始做直播了。目標是一個月內構建直播的閉環能力,也就是快速上線。需要實現發起直播、觀看直播(1人發起,多人觀看)、回看直播(回放)、直播互動(直播間中的評論、送禮等)、直播沈澱(Feeds沈澱、分享直播等)等功能(可參考圖1);且同時支持Android、iOS、Html5三大平臺(即方案成熟),並且支持空間以及手機QQ內的空間。

技術分享

首先我們就面臨項目工期緊張、團隊直播技術積累不夠的問題。雖然如此,但我們仍然硬著頭皮繼續與各大相關技術提供商進行交流,根據我們的標準以及提供商的建議進行技術選型,我們的標準如下:
● 專業度好(直播低時延遲,支持全平臺、基礎服務建設好);
● 開放源代碼;
● 支持度高,有問題可以隨時溝通解決;
● 支持動態擴容。

最後根據標準選擇了騰訊雲提供的ILVB直播解決方案,尤其音視頻相關組在這塊有多年技術積累,並且同部門可合作共贏。
這其中值得一提的是我們的閉環研發模式也促使我們以及合作夥伴不斷提升產品質量。首先快速上線(完成產品需求,並完善監控),再在上線後查看監控數據(分析數據),接著應用到優化工作(跟進數據、專項優化),最後進行灰度驗證(灰度一部分用戶驗證優化效果),根據效果再決定是否正式應用到產品中(如圖2)。

技術分享

最後,我們如願實現了1個月上線,同時支持QQ空間和手機QQ(結合版QQ空間),到目前為止已經叠代12+版本。觀看量也從5月份的百萬級到8月份的千萬級、到現在的億級,成為用戶參與的大眾化全民直播。產品數據也跟隨用戶的需求一直在飆升,隨之而來的是各種各樣的問題反饋,尤其是性能問題,這也是本文要重點討論的話題。

二、直播架構

在介紹直播架構前,我想有必要給大家再復習一下H264編碼,目前市面上直播的視頻編碼基本都是H.264。H264有三種幀類型:完整編碼的幀叫I幀、參考之前的I幀生成的只包含差異部分編碼的幀叫P幀、還有一種參考前後的幀編碼的幀叫B幀。H264的壓縮流程為分組(把幾幀數據分為一個GOP,一個幀序列)、定義幀類型、預測幀(以I幀做為基礎幀,以I幀預測P幀,再由I幀和P幀預測B幀)、數據傳輸。
用簡單的例子來解釋視頻模型,如果把一個GOP(Group of pictures)當做一列拉貨的火車,那一段視頻就是N輛火車組成的貨運車隊(圖3)。

技術分享

直播就是視頻數據的流動,邊拍攝、邊傳輸、邊播放的數據流動過程。數據由主播生產裝車,經過網絡(鐵路),再到觀眾端卸貨並進行播放消費。
火車需要調度,視頻流也一樣,這就是視頻流協議,即通過協議控制視頻有序的傳輸給觀眾。
常見協議如圖4:

技術分享

我們采用的是騰訊雲基於UDP開發的QAVSDK協議。

前面講了協議相關的內容,下面講講我們的直播模型,如圖5:

技術分享

視頻房間(視頻流)以及業務房間(相關業務邏輯互動)大致結構差不多,差別在於數據流動(註意圖5中箭頭)。
視頻房間數據由主播通過視頻流協議流向視頻服務器,而視頻服務器也通過視頻流協議把數據下發給觀眾,觀眾端解碼並播放。主播只上傳,觀眾只下載。而業務房間任何人都需要給服務器發送相關的業務請求(如評論,當然客戶端會屏蔽一些特殊邏輯,如主播不可送禮給自己)。更詳細的結構如圖6:

技術分享

註:iOS手Q觀眾采用RTMP協議不是因為不支持QAVSDK,而是因為手Q有減包壓力,而QAVSDK相關的SDK占用空間較大。

三、技術優化

接下來進入本文的重頭戲:技術優化。技術優化分為四個方面:秒開優化(耗時類優化實踐)、性能優化(性能優化實踐)、卡頓優化(問題分析類實踐)、回放優化(成本類優化實踐)。
在優化之前,我們的必要工作是監控統計先行,我們會對我們關心的數據點進行前期的統計,並做相關報表和告警,以輔助優化分析。
監控分為以下五部分:
● 成功率,發起直播成功率、觀看直播成功率、錯誤占比列表;
● 耗時,發起直播耗時、進入直播耗時;
● 直播質量,卡幀率、0幀率;
● 問題定位,各步驟流水、直播2s流水、客戶端日誌;
● 實時告警,短信、微信等方式。

通過這些,我們實現了數據的查看、分析定位、以及實時的告警,從而更方便地解決問題。

四、秒開優化

幾乎所有人都在吐槽“為什麽直播打開很慢,競品比我們快多了!!!”,我們自己也覺得不能忍。我們要讓觀看直播達到秒開(從點擊直播到看到畫面,耗時在1秒以內),而統計到的外網平均打開耗時為4.27秒,離秒開還有一定的差距。
於是我們梳理從點開到渲染第一幀畫面這一段時間的時序關系,同時統計各階段的耗時。流程圖和耗時大致如圖7 :

技術分享

通過流程分析和數據分析發現兩個耗時原因是:獲取首幀數據耗時太長、核心邏輯串行。接下來我們針對這兩個問題進行優化。
首幀耗時太長。核心問題在於加速首個GOP到達觀眾的時間。
我們的優化方案是:讓接口機緩存首幀數據,同時對播放器進行改造,解析到I幀就開始播放。這樣大大加快了觀眾看到首幀的時間。
核心邏輯串行。這部分我們主要通過以下流程:
● 預加載,提前準備環境和數據,如在feeds中提前預拉起直播進程,提前獲取接口機IP數據;
● 延遲加載,對UI、評論等其他邏輯進行延遲加載,讓出系統資源給首幀;
● 緩存,如緩存接口機IP數據,一段時間內復用;
● 串行變並行,同時拉取數據,節省時間;
● 對單步驟耗時邏輯進行優化和梳理,減少單步耗時。
優化後的流程和耗時大致如圖8所示,耗時降低到680ms,目標達成!

技術分享

五、性能優化

產品不斷叠代,直播的玩法也越來越豐富了,同時一些性能問題也不斷暴露出來。尤其我們後來增加了動效貼紙、濾鏡、變聲等功能,大量用戶反饋直播很卡。
通過統計發現:主播短幀率很低,畫面不連續,主觀感覺卡;另外,用戶使用設備中也有大量的低端機。如圖9所示。

技術分享

通過分析發現幀率低的主要原因是單幀圖像處理耗時過長導致,而編碼所占因素較低。一般總耗時=處理工作量*單幀耗時。於是我們逐漸對這兩方面進行優化。

減少圖像處理工作量
● 采集分辨率與處理分辨率一致,比如編碼為960×540,由於有些手機可能不支持這個采集分辨率,采集一般都是1280*1024,之前處理是先處理再縮放,現在先縮放再處理,減少圖像在濾鏡、動效貼紙中的處理耗時。如圖10

技術分享

● 處理幀前丟幀。雖然我們對系統相機設置了采集幀率,但是很多機型並不生效,於是我們通過策略對額外的幀進行丟棄,減少圖像處理的幀數。比如我們設置采集幀率為15,但實際有25,這多余的10幀處理了在編碼的時候也會浪費,之前就丟棄,可減少資源消耗。
● 機型分檔位,不同的機型根據不同的硬件能力采用不用的采集幀率和編碼幀率,保證流暢;同時在過熱的時候以及回歸正常時動態調整幀率去調整資源消耗。
● 人臉識別采集優化,每幀識別改為兩幀識別一次人臉,既不會產生人臉漂移也可以減少處理耗時。
減少單幀耗時
● 采集流程改造,減少了大約33%的不必要耗時,如圖11.

技術分享

● 動效貼紙多GL線程渲染,貼紙渲染放在另外一個OffScreenThread進行渲染,完全不占用整個美化處理過程的時間,效果如圖12:

技術分享

● 動效貼紙采用OpenGL混合模式;
● 圖像處理算法優化,如ShareBuffer優化(實現在GPU與內存之間快速拷貝數據,排除CPU介入,節省紋理轉RGBA時間;耗時幾乎降低一半,FPS也至少提升2-3幀左右),濾鏡LUT優化,如圖13.

技術分享

除了以上兩個大的優化點,我們還推動更多的機器采用硬件編碼。首先編碼穩定,幀率不會波動;其次,占用CPU會有一定降低。
以上是我們大致的一些優化點,優化之後,用戶直播投訴大量減少。

六、卡頓優化

我們先看一些相關的定義:
卡頓用戶定義:(卡頓時長/總時長)>5%定義為卡頓用戶,卡頓率=卡頓用戶/總用戶。
主播卡頓點定義:上行大畫面編碼後幀率<5的點數。
觀眾卡頓點定義:解碼後幀率<5的點數。
我們的目標就是讓卡頓率達到50%以下。
當然上行發生卡頓時,會造成所有用戶卡頓,而下行卡頓時,只有單個觀眾才會卡頓。
我們看看會造成卡頓的原因,見圖14 :

技術分享

大概有主播端、網絡、觀眾端三個大的模塊可能會導致卡頓問題,而主播端的性能優化基本解決了,那就看下網絡以及觀眾端的。
從統計數據發現網絡質量影響占比達到50%左右,這明顯要優化。於是網絡上行優化我們做了圖15的事情,減少單幀中的數據以及減少幀數,用火車的例子就是減少貨物以及控制火車數量。

技術分享

而用戶端下行優化則是囤積貨物,丟掉貨物,如圖16 。

技術分享

如圖17,我們來看優化後的效果,與競品相比優勢十分明顯:

技術分享

同時,主播卡頓率也下降到30%,觀眾卡頓率下降到40%,目標算是達成了。

七、回放優化

如圖18,我們先來看看直播回看(回放)的大致流程:

技術分享

回放同樣也存在一些問題,主要體現在兩個方面:
● 回放直播質量:服務器器端保存,回看視頻質量受主播短網絡影響較大
● 服務器成本:服務器除了需要推一個私有協議流,另外還需要對私有流進行轉碼成HLS和MP4以便回放使用

在方案選擇上,MP4具有播放方案成熟、速度快、用戶體驗佳等優點;而HLS系統支持差、用戶等待時間也長。那是否意味著我們要直接選擇MP4方案呢?
其實回看采用HLS以及MP4都是可以的,但是直播觀看時由於數據是在變化的,HTML5只能使用HLS,如果我們回看的時候使用MP4,那就等於服務器需要對私有協議流分別轉碼成MP4和HLS,那這明顯不經濟。這就致使我們選擇HLS,服務器只需要轉碼一次流為HLS即可。
既然選擇HLS,我們就要針對性地解決HLS存在的問題。
在Android平臺上,Android 3.0開始支持HLS,後來因為Google官方想推DASH取代HLS,對HLS的支持便慢慢減弱了,在官方文檔上甚至找不到一點兒關於HLS的說明。經實踐發現Android原生播放器對HLS的支持程度僅僅是能播,完全沒有任何優化。這樣不僅會有多余的m3u8文件請求,而且啟動播放後整個流程是串行的,非常影響視頻畫面的首幀可見耗時(平均耗時4.5s左右)。
我們可以通過本地代理提前下載來解決這個問題,接入下載代理後,在代理層可以對m3u8文件的內容進行掃描,並觸發對ts分片的並行下載,把ts數據緩存起來。經過這樣的處理後,雖然播放器的層面還是串行下載,由於我們已經提前準備好了數據,數據會很快返回給播放器,這樣就實現了我們降低首幀耗時的效果,經實驗接入後平均首幀可見耗時降低到了2s左右。
優化前後流程圖見圖19:

技術分享

緩存策略上,HLS的緩存業界目前還沒有成熟方案。我們實現了對圖20中三種模式的自動偵測與支持,使用方完全不需要關心底層的緩存與下載邏輯。

技術分享

最後,服務器成本方面節省了50%的轉碼計算和存儲成本;另外,回放的加載速度也變快了。

八、案例總結

通過之前的案例和相關優化分析,總結出三種大致的問題模式,以及相應的優化思路。
● 速度類:理清時序,統計各階段耗時,各個擊破;
● 性能類:通過Trace,明確性能損耗點,各個擊破;
問題解決類:建立模型,初步分析,統計上報,確認問題,各個擊破。

總結成一個套路就是圖21 :

技術分享

在案例中也體現了以下一些參考點:
● 快速叠代,小步快跑
● 監控驅動優化
● 建立模型,抽象問題直觀分析
● 產品定位決定優化的方向
● 海量服務,以小省大

最後,以一張空間直播的拓補圖作為結束本文(圖22)。

技術分享

TOP100全球軟件案例研究峰會已舉辦六屆,甄選全球軟件研發優秀案例,每年參會者達2000人次。包含產品、團隊、架構、運維、大數據、人工智能等多個技術專場,現場學習谷歌、微軟、騰訊、阿裏、百度等一線互聯網企業的最新研發實踐。大會開幕式單天體驗票申請入口

TOP100summit:【分享實錄-QQ空間】10億級直播背後的技術優化