對話架構師:億級短視頻社交美拍架構實戰

雲計算 軟件 Java MySQL 高峰 Java高級架構技術 2018-12-02

筆者休閒之餘看到了一篇之前的文章,仔細看了一下關於美拍APP的架構思想,優劣之處無以評價,頗有感觸,特“拿來”分享給大家。

“在美拍的服務化過程中,主要基於 etcd 來實現我們的動態服務發現和配置服務,在 client 層面擴展實現了包含負載均衡、心跳、節點健康狀態探測、etcd 節點掛掉的災備等基礎功能,同時會通過一些 metrics 埋點,以便跟蹤內部的狀態,用統一的 trace_id 來跟蹤服務的鏈路調用情況。” —— 麥俊生

一、短視頻市場的發展

近幾年來,短視頻應用在國內應用市場引爆,美圖公司推出了美拍,相關的產品還有 抖音、GIF 快手、秒拍、微視、逗拍、玩拍等,一系列短視頻產品的出現也豐富了短視頻應用市場。

短視頻的相繼爆發,與幾個因素有關:

1、帶寬,隨著中國基礎網絡環境的發展,越來越多的2G移動網民開始轉向使用 3G/4G 網絡,從而體驗到更好的上傳下載帶寬和更穩定的網絡, 目前 3G/4G 的移動用戶比例大概佔比 85% 以上;同時隨著資費的進一步降低,月戶平均流量也達到了 360M,甚至不少部分是 GB 甚至幾十 GB 的級別的流量,所以就一個普通的 10s 視頻而言大概不到 1~2M 甚至幾百 K,帶寬流量的提升無疑會逐步降低用戶使用的門檻;此外,家用帶寬也隨之增加,目前 10M 甚至 100M `已經成為家用帶寬的主流,從而為短視頻的發展提供了必要條件。

2、手機硬件配置的極大改進,隨著像素的增加、手機硬件配置 CPU、GPU、內存等的升級,能夠讓手機更快的來處理和優化視頻效果,從而能夠給手機視頻的處理帶來更多的創意空間。

3、傳統的文字和圖片的表達能力不夠豐富,所以無法滿足網民的需求,而短視頻帶來了足夠大的表現空間。

4、產品本身,提供了各種方式來降低用戶視頻的製作門檻,比如美拍提供了 MV 特效等,來提升了製作視頻的趣味性的同時,降低使用的門檻。同時產品的多樣化,也滿足了各種用戶的差異化需求,激發用戶自傳播。

二、美拍的發展

美拍在 2014.05 月發佈,上線僅 1 天,即登入 App Store 免費總榜第一,當月下載量排名第一。在發佈 9 個月的時候,用戶就突破 1 個億。目前每天美拍視頻日播放量在 2.7 億以上,日視頻播放時長達到 183 萬小時。

面臨這種用戶量爆發的增長,美拍也遇到了很多應用起步之初那些年所遇到的甜蜜和苦澀的回憶,經過 1 年多的架構的演進,美拍也積累了一定的經驗,形成了一套高可用高可擴展的架構實踐。雖無法做到很華麗,卻會隨著架構的不斷的演進而不斷的完善。

相比於普通的文本社交類 APP,做這麼一個短視頻產品在技術架構層面,會面臨哪些問題呢?

對話架構師:億級短視頻社交美拍架構實戰

和通用的文本社交類產品一樣,美拍有首頁熱門、好友動態(feed 流)、評論服務、私信服務等基礎功能;所以在用戶爆發增長後,同樣會面臨應用層、數據庫、緩存、接入層等方面的挑戰,那麼如何做到低延遲、高可用呢。同時因為是短視頻本身,也會面臨一些特定的領域性相關的問題。

三、短視頻所面臨的架構問題

短視頻相比於文本數據而言,有著一些差異:

1、數據大小的差異

比如一條美拍,經過視頻壓縮和清晰度的權衡,10s 的視頻大小 1MB 多,而一條 5 分鐘視頻的美拍甚至要達到幾十 M,相比與幾十字節或者幾百字節的文本要大得多。因為數據量要大得多,所以也會面臨一些問題:如何上傳、如何存放、以及如何播放的問題。

關於上傳,要在手機上傳這麼一個視頻,特別是弱網環境要上傳這麼一個文件,上傳的成功率會比較低,晚高峰的時候,省際網絡的擁塞情況下,要更為明顯得多。所以針對上傳,需要基於 CDN 走動態加速來優化網絡鏈路(通過基調實測過對於提升穩定性和速度有一定幫助),同時對於比較大的視頻需要做好分片上傳,減少失敗重傳的成本和失敗概率等來提升可用性。同時不同 CDN 廠商的鏈路狀況在不同的運營商不同地區可能表現不一,所以也需要結合基調測試,選擇一些比較適合自己的 CDN 廠商鏈路。

同時因為數據相對比較大,當數據量達到一定規模,存儲容量會面臨一些挑戰,目前美拍的視頻容量級別也達到 PB 級別的規模,所以要求存儲本身能夠具備比較強的線性擴展能力,並且有足夠的資源冗餘,而傳統的 MySQL 等數據庫比較難來支持這個場景,所以往往需要藉助於專用的分佈式對象存儲。可以通過自建的服務或者雲存儲服務來解決。得益於近幾年雲存儲的發展,目前美拍主要還是使用雲存儲服務來解決。自身的分佈式對象存儲主要用於解決一些內部場景,比如對於數據隱私性和安全性要求比較高的場景。

播放方面,因為文件比較大,也容易受到網絡的影響,所以為了規避卡頓,一些細節也需要處理。比如對於 60s,300s 的視頻,需要考慮到文件比較大,同時有拖動的需求,所以一般使用 http range 的方式,或者基於 HLS 的點播播放方式,基於前者比較簡單粗暴,不過基於播放器的機制,也能夠滿足需求,也能實現點播拖動。而直接基於 HLS 的方式會更友好,特別是更長的一些視頻,比如 5 分鐘甚至更大的視頻,不過這種需要單獨的轉碼支持。之前美拍主要是短視頻為主,所以更多使用 http range 的方式。而後續隨著 5 分鐘或者更大視頻的場景,也在逐步做一些嘗試。同時對於播放而言,在弱網環境下,可能也會面臨一些問題,比如播放時卡頓的問題,這種一般通過網絡鏈路優化;或者通過多碼率的自適應優化,比如多路轉碼,然後根據特定算法模型量化用戶網絡情況進行選碼率,網絡差的用低碼率的方式。

2、數據的格式標準差異

相比於文本數據,短視頻本身是二進制數據,有比較固定的編碼標準,比如 H.264、H.265 等,有著比較固定和通用的一些格式標準。

3、數據的處理需求

視頻本身能夠承載的信息比較多,所以會面臨有大量的數據處理需求,比如水印、幀縮略圖、轉碼等。而視頻處理的操作是非常慢的,會帶來巨大的資源開銷。

美拍對於視頻的處理,主要分為兩塊:

客戶端處理,視頻處理儘量往客戶端靠,利用現有強大的手機處理性能來減少服務器壓力, 同時這也會面臨一些低端機型的處理效率問題,不過特別低端的機型用於上傳美拍本身比較少數,所以問題不算明顯。客戶端主要是對於視頻的效果疊加、人臉識別和各種美顏美化算法的處理,我們這邊客戶端有實驗室團隊,在專門做這種效果算法的優化工作。同時客戶端處理還會增加一些必要的轉碼和水印的視頻處理。目前客戶端的視頻編解碼方式,會有軟編碼和硬編碼的方式,軟編碼主要是兼容性比較好,編碼效果好些,不過缺點就是能耗高且慢些。而硬編碼藉助於顯卡等,能夠得到比較低的能耗並且更快,不過兼容和效果要差一些,特別是對於一些低配的機型。所以目前往往採用結合的方式。

服務端的處理,主要是進行視頻的一些審核轉碼工作,也有一些抽幀生成截圖的工作等,目前使用 ffmpeg 進行一些處理。服務端本身需要考慮的一些點,就是因為資源消耗比較高,所以需要機器數會更多,所以在服務端做的視頻處理操作,會盡量控制在一個合理的範圍。同時因為美拍這種場景,也會遇到這些熱點事件的突變峰值,所以轉碼服務集群本身需要具備可彈性伸縮和異步化消峰機制,以便來適應這種突增請求的場景。

四、為支持億級用戶,美拍架構所做的一些改進

隨著用戶和訪問量的快速增長,美拍遇到不少的挑戰

  • 性能的挑戰
  • 可用性的挑戰
  • 突發熱點的挑戰
  • 業務頻繁迭代的挑戰

在頻繁的業務迭代的情況下,如何能夠在海量請求下保證足夠高的可用性,同時以一個比較好的用戶體驗和比較低的成本的方式來提供服務成為我們努力的方向。

這個是目前美拍的整體架構全貌

對話架構師:億級短視頻社交美拍架構實戰

這一個架構目前也正在不斷的持續演進的過程中,除了一些基礎服務組件的建設外,我們還著重在服務治理做一些相關工作,來保證整體服務的可用和穩定。

對話架構師:億級短視頻社交美拍架構實戰

分而治之、化繁為簡

規劃整體架構,明確服務模塊的單一職責,儘量保持足夠內聚,而服務模塊之間做到解耦,這樣就能夠針對單一模塊進行更精細化的優化工作,同時能夠用適合的技術來解決適合的場景問題。

服務之間的交互和通訊,我們主要走了兩種方式:

  • 基於 HTTP 的方式
  • 基於 config service + RPC 的方式

前者使用的方式比較簡單,目前我們主要在跨團隊、跨語言(比如 PHP 和 golang 之類的)會使用,主要會在七層 nginx 層做一些工作,如負載均衡、節點探測、併發保護等。

對話架構師:億級短視頻社交美拍架構實戰

而第二種方式,我們主要用於內部系統之間的一些交互。目前我們主要基於 etcd 來實現我們的動態服務發現和配置服務,在 client 層面擴展實現了包含負載均衡、心跳、節點健康狀態探測、etcd 節點掛掉的災備等基礎功能,同時會通過一些metrics埋點,以便跟蹤內部的狀態,用統一的 trace_id 來跟蹤服務的鏈路調用情況。

對話架構師:億級短視頻社交美拍架構實戰

開放擴展

主要針對下面幾個點:

  • 代碼功能的可擴展性
  • 交互協議的擴展性
  • 數據存儲格式的可擴展性
  • 應用的可擴展性
  • 資源的可擴展性

交互協議,既針對交互接口,也針對 app 客戶端和服務端的交互協議。特點是 app 客戶端和服務端的交互協議,因為 app 的升級較之服務端升級的時間久得多,比如你發佈了一個客戶端版本 V0.1,如果用戶後面一直不升級,這個時間可能是幾個月、半年甚至一年,那麼就會引入一些兼容問題,所以在協議層面設計的關鍵點需要考慮這種情況的存在,需要保證協議能夠向前兼容,預留好擴展點。

而關於數據存儲格式的可擴展性,美拍第一個版本每個屬性在數據庫中為一個字段,並且為了保持一定的擴展性也多加了幾個擴展字段。在發展過程中演化為所有屬性字段序列化為 protocol buffer 數據的方式,這樣能更好滿足快速發展的業務需求。但是大家往往也更多關注在服務端,其實有時候比較坑的是在客戶端。之前就踩過坑客戶端上有個 id 字段的數據類型使用 int32,因為客戶端基本很難做強升,一個這樣小的事情最終需要很長時間來消化解決,並且為此還需要做一些兼容工作。所以針對這類事情,建議大家在一開始時候也多留意,儘量少為將來埋坑。

分級隔離

目前我們主要通過這幾個維度進行一些隔離:

  • 核心和非核心的隔離
  • 單一集群的內部隔離
  • 不同集群的外部物理資源隔離
  • 不同集群的外部依賴資源的隔離
對話架構師:億級短視頻社交美拍架構實戰

美拍在發展早期,跟多數發展早期的系統一樣,也是多數接口部署在同一個集群中,包括也共用了一些資源(比如 memcached ),這樣的好處是早期部署上足夠的簡單。在發展的過程中,業務在快速發展,業務複雜度也在逐步提升,接口調用量也急劇增加,逐步就暴露出一些問題。美拍的發展過程也是實際的去驗證了前面提到的分級隔離機制。

在發展早期,曾經有個調用量不小的非核心的業務,在對存儲數據結構做了調整後的上線過程中出現性能問題,導致整個集群服務都受到一定的影響。雖然通過降級策略和運維配套設施快速的解決了問題,但是也引發了我們的進一步思考。在架構上我們會盡量保證在開發效率、系統架構、部署和運維成本等方面達到一定的平衡,以避免過度設計或者架構支撐不了業務。這到了需要做一些事情的時候,我們把核心業務和非核心業務在七層和應用層做了部署上的隔離。

做完上面的核心業務和非核心業務拆分之後,接口互相之間的依賴影響降低很多。但是還沒有解決核心業務或者非核心業務內部接口之間的依賴影響問題。所以接下來也更進一步,針對部分場景也做了內部隔離,通過限定每個接口最多隻能使用的固定處理線程數方式,來避免因為單個集群內某個接口的問題導致整個集群出問題的情況發生。

以上主要是在接口層面做隔離,而在依賴的資源及其外部服務方面,如果沒有相應的隔離機制,也會有互相依賴影響的問題,比較典型的有 memcached slab calcification 問題等。所以我們也在 memcached、mysql 等核心資源層面做了拆分。

綜合來看,分級隔離本質上也是在解決服務之間依賴影響問題。

資源冗餘

因為短視頻是一個比較耗帶寬的服務,因此在通用的應用自身資源冗餘的情況下,還需要考慮到服務所依賴的外部資源,比如 CDN 和雲存儲服務本身的情況。對於 CDN 層面,可能還要考慮不同廠商在不同區域不同運營商下的資源冗餘情況。而依賴的雲服務等,這些服務本身從對外角度看是一個可無限擴展的服務,理論上通過擴展就能夠滿足性能需求,但是在使用往往會受限於實現,因為內部不一定是一個完全隔離的場景,比如說和別的企業服務混跑,同時可能只會分配對應的資源池,但這個資源超過性能預期的時候,不是一個可自動動態伸縮調度的場景。

容災

美拍的容災主要分為自身服務容災、CDN容災、雲存儲容災等。

自身服務容災主要包含一些典型的容災場景,比如 cache 容災,通過多級 cache、cache 的分片 hash 的方式、以及本地 cache 的方式來解決。目前我們這邊的容災也借鑑了微博的多級 cache 機制的機制,針對核心的 cache 資源會有主備節點,避免單一節點掛掉後,穿透會壓垮後端 DB,同時對於請求量特別大的場景,比如對於某個熱點資源訪問量很大的情況下,也會在之前增加一層 L1 的 LRU cache 來規避和緩解這一問題。

對話架構師:億級短視頻社交美拍架構實戰

CDN 容災主要通過接入多家供應商進行互備,然後通過一些基調檢測不同服務廠商的鏈路和服務狀態,當發現服務有問題的時候,通過 DNS 進行區域的切換。不過不同 CDN 廠商的服務表現不對等,所以在選型 CDN 廠商的話,需要側重關注可用性、節點布點和鏈路狀況、回源量、資源冗餘量、晚高峰的鏈路狀況、以及對於多媒體是否有單獨優化等等來評估靠譜性。

雲存儲容災,目前美拍也主要使用兩家互備的方式,因為國內的網絡鏈路狀況容易發生問題容易導致個別上傳服務失敗,以及雲服務廠商服務掛掉的情況我們需要保證我們的服務可用。目前的做法是上傳優先走主的雲服務,如果上傳失敗的話,那麼就會啟用備的雲服務。然後服務端層面也可以控制整體降級的方式,可以直接從主雲服務直接降級讀寫備雲服務。 基於每天的統計來看,通過這個方式至少提升上傳的 0.1% 以上的可用性,在某些極端情況下,可能達到 1% 的可用性,當然這一塊通過網絡鏈路優化可能使得可用性情況沒有數據中那麼差。不過他的主要作用是在當某個雲服務廠商節點服務出現短暫不可用或者長時間不可用的時候,我們也不會受太大影響。

對話架構師:億級短視頻社交美拍架構實戰

五、後續的一些發展

隨著短視頻的不斷的發展,以及實時直播的崛起,帶寬的壓力會越來越大,所以能夠結合著 P2P + CDN 的方式來緩解服務端的帶寬壓力,不過 P2P 主要會面臨著防火牆的問題、以及節點網絡質量的影響,同時也依賴與視頻播放的熱度,這種對於效果都會有一些影響,同時為了更好的播放流暢度,單一的 P2P 無法滿足需求,需要基於 P2P 和 CDN 的輔助進行。

帶寬的另外一個節省之道,就是通過更好的編碼標準來進行優化,比如 H.265 的編碼標準,通過這個能夠節省一半的流量。不過目前 H.265 在硬編支持不是很好,只有個別手機機型支持,而軟編碼的方式相比與 H.264,編解碼速度要慢個幾倍,這種對於能耗消耗比較高,處理也比較慢。而在往 H.265 演化的過程中,解碼的普及程度也將會比編碼來得更早。因為在解碼算法層面,現有開源的方案還有很大的優化空間,以現有的手機硬件配置,是存在可以通過算法優化達到可以支撐 H.265 的空間。所以隨著解碼算法的不斷優化和硬件的不斷升級,解碼普及的時間點也應該會比大家預期的時間來得更早,晉時也將會有更大比例的端能支持 H.265 的解碼,對於 H.265 的普及奠定了很好的基礎。

H.265 的普及理想情況是需要很大比例的端上設備在編碼和解碼層面都有支持,在解碼更早普及的情況下,那麼其實是有一種中間過渡方式:上傳端上傳 H.264 數據,服務端轉為 H.265,播放端根據自身機器狀況選擇使用 H.264 或者 H.265 數據。這樣的方案需要服務端需要額外做一次轉碼,並且存儲成本也會提升。在有更大比例的端上支持 H.265 後,這樣雖然有額外的成本開銷,但是相比使用 H.265 帶來的帶寬成本的節省可能就越來越可以忽略掉。並且也可以根據訪問熱度情況做控制,取得兩者更好的平衡。

另外一個方向,目前美拍會越多越多的把一些客戶端的圖片視頻美化算法雲端化,以服務的形式暴露給內部其他服務使用,以便能夠支撐更多圍繞“美”體系建設的產品生態鏈。這主要會面臨的架構難點,就是資源消耗高。而這個的解決會依賴與兩種方式,一種通過硬件 GPU、協處理器、CPU SIMD指令等來優化性能,同時還需要解決架構的視頻處理集群的自動彈性調度的問題,同時對於一些場景,比如類似與 H5 的推廣頁面,會逐步通過結合公有云調度的方式來解決。

關注我:私信回覆“架構視頻資料”獲取往期Java高級架構資料、源碼、筆記、視頻、BATJ面試視頻資料

對話架構師:億級短視頻社交美拍架構實戰

相關推薦

推薦中...