開發與維運

如何構建一套高性能、高可用性、低成本的視頻處理系統?

前言

近些年,在線教育行業飛速發展,為整個社會的知識傳播提供了前所未有的便利性。通過多種形式的在線教育平臺,學員與教師即使相隔萬里也可以開展教學活動。藉助豐富的網絡課件,學員還可以隨時隨地的進行學習,真正打破了時間和空間的限制。在各種形式的網絡課件中,視頻課件自然是最直觀表現力最豐富的形式,因此視頻課件的市場佔有率也在逐年提升。

視頻處理需求分析

對於在線教育領域的視頻課件出品方而言,每天都要對大量視頻內容進行處理,下圖展示了一個比較典型的場景:

image.png
1、用戶上傳一個視頻到平臺後,會先在對象存儲中對視頻源文件進行暫存。
2、平臺對視頻進行預處理,並打上水印。
3、平臺將視頻文件轉換為其他格式,並對分辨率進行調整,以適配各種不同的終端設備的要求。
4、將處理好的視頻文件保存回對象存儲,並同步到 CDN 進行加速。

雖然從流程上來講,這個場景比較簡單,但在技術上的挑戰其實是非常大的。視頻課件的原作者來自於在線教育平臺的廣大用戶,可能是平臺負責內容輸出的內部用戶,也有可能是簽約的教師,或者是平臺認證過的分享型用戶。用戶上傳視頻的操作並沒有固定的頻率,往往集中在幾個時間段,存在明顯的波峰波谷。在業務高峰期,視頻處理的需求量非常大,有的在線教育企業每天要完成數萬個視頻的轉碼工作。對於負責建設視頻處理系統的技術團隊而言,這樣的業務場景就留給了他們一系列的挑戰:

1、如何確保這套系統在業務高峰期的高可用性?
2、如何讓每一個上傳的視頻儘可能快的處理完?
3、如何儘可能的降低資源成本?
4、如何高效率的應對需求的頻繁變更?

基於這幾個訴求,我們結合雲計算的特點,來分析一下可行的解決方案。

使用 SaaS 化的雲服務完成視頻處理

隨著各大雲計算廠商產品線的不斷豐富,我們可以很輕鬆的尋找到開箱即用的方案來解決這類典型的視頻處理需求。以阿里云為例,視頻點播類產品提供了視頻採集、編輯、上傳、媒體資源管理、轉碼處理、視頻審核分析、分發加速於一體的一站式解決方案。

image.png
對於技術團隊而言,採用這樣的方案不用預先準備任何計算資源,甚至不用編寫任何代碼,就能夠從無到有擁有一整套視頻處理系統,完全不用考慮資源規劃的問題。這樣的方案非常適合在業務發展初級需要讓系統快速上線的場景。

但隨著業務的不斷髮展,開箱即用的 SaaS 化方案還是存在不少的侷限性,基於如下的原因,大多數的技術團隊還是會選擇自己建設視頻處理系統:

1、對於之前已經通過 FFmpeg 技術實現的視頻處理服務,因為涉及到複雜的業務邏輯,很難直接遷移到 SaaS 化方案上來。

2、高階的視頻處理需求必須使用代碼來實現:比如音頻降噪、插入動態 Gif 水印、按固定頻率截幀等等。

3、使用高分辨率的大視頻是行業趨勢,對於超大視頻的處理,比如 10G 以上的 1080P 視頻,往往需要通過自定義的手段進行計算優化,才能保證處理的及時性。

4、在很多種場景下,自建視頻處理系統都會帶來明顯的成本優勢。

5、頻繁的業務需求變更需要對整套系統進行更精細粒度的迭代管理,比如採用金絲雀策略降低新版本發佈所帶來的風險。

那麼如何建設一套同時具備高性能、高可用性、高靈活性、低成本特點的視頻處理系統呢?

基於分佈式集群

最典型的方案是申請一組雲虛擬機,在每臺虛擬機上部署視頻處理應用,組建成一個可以水平伸縮的服務集服。當有新的上頻上傳的時候,可以觸發一個處理任務,並通過負載均衡或消息隊列對任務進行分發,接到任務的應用節點負責完成對應的任務。

image.png
通過這個架構,在業務高峰期,用戶上傳視頻行為比較密集,可以增加服務集群的實例數量,來提升處理能力。在業務低峰期,可以減少服務集群的實例數量,來減少資源成本。

此方案可以通過定製化的代碼邏輯實現各種高階的視頻處理需求,靈活度非常高,配合可以水平伸縮的計算集群以及負載均衡機制,能同時滿足性能和成本方面的需求,是一套被廣泛採納的方案。但在生產環境大規模運行的情況下,這套方案還是會暴露出很多問題:

維護工作量大。整套系統的維護工作量涵蓋了虛擬機、網絡、負載均衡組件、操作系統、應用等多個層面,需要投入大量的時間和精力來保障系統的高可用性與穩定性。舉一個最簡單的例子,當某個應用實例出現故障的時候,如何第一時間定位故障並儘可能迅速的將其從計算集群中摘除,摘除之後又如何保證之前沒有完成的任務能夠重新得到處理呢?這些都需要再配合完整的監控機制、故障隔離恢復機制來實現,甚至涉及到代碼層的業務邏輯優化。

彈性伸縮能力滯後。有兩種方式實現計算集群的彈性伸縮:通過定時任務觸發,或者通過指標閾值(CPU利用率,內存使用率等)觸發。不管採用哪種方式,都沒有辦法基於用戶行為精細化管理,在遇到任務密度大幅度起伏的時候,會面臨彈性伸縮能力滯後的問題。當來自用戶的視頻上傳請求突增的時候,新增一個應用實例需要經過申請雲資源>初始化>部署應用鏡像>應用啟動>加入負載均衡列表等多個階段,即便通過 Kubernetes + 預留資源池等技術優化,也往往需要 10 分鐘以上。

資源利用率低。滯後的彈性伸縮能力會導致伸縮策略制定的相對保守,造成計算資源的大量浪費,增加了使用成本,如下圖所示:
image.png
有沒有一種方案能能幫助技術團隊專注於業務邏輯的實現,並可以根據用戶的實際上傳請求進行精細化的資源分配,實現資源利用最大化呢?隨著雲計算的飛速發展,各大雲廠商都在積極探索新的方案,用更加“雲原生”的方式來解決成本和效率的問題,阿里雲提供的函數計算 + Serverless 工作流就是這個領域非常具有代表性的方案。

函數計算

阿里雲函數計算是事件驅動的全託管計算服務。通過函數計算,開發者無需管理服務器等基礎設施,只需編寫代碼並上傳。函數計算會為自動準備好計算資源,以彈性、可靠的方式運行代碼,並提供日誌查詢、性能監控、報警等功能,確保系統的穩定運行。

相比傳統的應用服務器保持運行狀態並對外提供服務的方式,函數計算最大的區別是按需拉起計算資源對任務進行處理,在任務完成以後自動的回收計算資源,這是一種真正符合 Serverless 理念的方案,能最大化的提升資源利用率,減少系統系統維護工作量和使用成本。因為不需要預先申請計算資源,使用者完全不需要考慮容量評估和彈性伸縮的問題,只需要根據資源的實際使用量來進行付費。

下圖展示了函數計算的工作方式:
image.png
對於使用者而言,把實現關鍵業務邏輯的代碼上傳到函數計算平臺,就能以事件驅動的方式觸發函數執行。函數計算已經支持各種主流的編程語言,對於即有的代碼,可以通過幾個非常簡單的步驟部署到函數計算。函數支持的所有開發語言請參考開發語言列表:

https://help.aliyun.com/document_detail/74712.html

每一次計算資源的分配,都基於事件的觸發,一個事件往往對應著業務上的一個任務。函數計算支持多種多樣的觸發器,比如HTTP觸發器的事件源就是 HTTP 請求,函數計算接收到一次 HTTP 請求後,會按照預設的規格,分配相應的計算資源來處理這個 HTTP 請求,請求處理完成之後,函數計算會根據用戶的設置決定是否立即回收這一次拉起的計算資源。而 OSS 觸發器,能夠監控發生在對象存儲 OSS 上的各種事件,當有用戶上傳新文件或者對文件進行修改的時候,自動觸發函數執行,這種方式就剛好適合視頻處理的業務場景。更多支持的函數觸發器請參考觸發器列表:

https://help.aliyun.com/document_detail/74707.html

在計算資源的調度上,函數計算進行了大量優化,面對用戶請求的突增,可以在毫秒級拉起大量的計算資源來並行工作,確保用戶體驗。

通過函數計算進行視頻處理

基於函數計算的特性,搭建一套視頻處理系統就非常簡單,只需要配置一個 OSS 觸發器,並將視頻處理的核心代碼上傳到函數計算,就大功告成:
image.png
通過這套方案,使用者不再需要考慮資源管理、負載均衡、系統高可用、彈性伸縮、系統監控等一系列複雜的問題,函數計算平臺會按最優的方式根據用戶的上傳行為調度計算資源,低成本高效率的完成視頻處理任務。具體的操作步驟和代碼實現可以參考視頻處理 Python 實現 Demo :

https://github.com/awesome-fc/simple-video-processing

在這個 Demo 中,演示瞭如何基於函數計算將用戶上傳的視頻統一轉為 640 * 480 分辨率的 mp4 格式視頻。

代碼開發

每一個創建好的函數都會對應一個指定的入口,函數計算會從這個函數入口開始執行,類似於本地開發中的 Main() 函數。以 Python 語言為列,一個簡單的入口函數如下:

def handler(event, context):
return 'hello world'

當有事件觸發的時候,就會從入口函數開始執行,其中 event 參數攜帶了事件源相關的信息,比如在視頻處理場景中,event 參數攜帶了上傳到 OSS 的 Bucket 以及文件名等信息。而 context 參數攜帶了函數的運行信息,包括函數名、超時時間、訪問憑證等。通過這些信息,就能讓執行代碼完成預定義的各種操作。

函數計算支持各種主流的編程語言,在這個編程語言當中, Node.js 和 Python 等腳本型語言含了豐富的類庫,開發效率很高,而且運算實例啟動的速度很快,能夠支持對延遲特別敏感的任務,是函數計算最匹配的語言。Java 和 Go 等語言不能像腳本型語言一樣直接上傳代碼就能創建一個函數,需要預先進行編譯,使用起來會稍微複雜一些,但配合函數計算提供的 Funcraft 等工具,也可以大幅度提升開發和部署的效率。不管使用哪種開發語言,都建議使用者下載官方提供的 Funcraft 工具,更輕鬆進行開發、構建、部署操作,請參考 Funcraft :

https://help.aliyun.com/document_detail/140283.html

像 Java 這樣的語言,在虛擬機啟動的時候需要加載比較多的類庫,不能夠像實現運算實例毫秒級啟動並進入執行狀態,不能直接使用在一些對於延遲特別敏感的業務場景。但配合函數計算提供的預留實例以及單實例多併發新功能,能夠消除冷啟動對業務的影響,並降低等待下游服務響應的影響,讓函數計算上運行的 Java 語言也能實現 API 網關等對延時要求特別高業務場景。請參考預留實例:

https://help.aliyun.com/document_detail/138103.html

和單實例多併發:

https://help.aliyun.com/document_detail/144586.html

Serverless 工作流

通過前面介紹的方案,可以輕鬆完成對短視頻的各種定製化處理。但每一個函數計算實例,在資源規格上和總運行時長都不是無限的,目前函數計算實例可以擁有 3G 的內存資源和 10 分鐘的執行時間,這也就說明,當一個視頻處理任務需要佔用 3G 以上的系統內存,或者總執行時長超過 10 分鐘的情況下,處理任務是會失敗的。

在 5G 時代,超大視頻課件是非常普遍的需求,如何通過函數計算處理這樣的大視頻呢?這個時候就要出動另一個武器--- Serverless 工作流,來配合函數計算一起完成這個任務。

Serverless 工作流是一個用來協調多個分佈式任務執行的全託管雲服務。您可以用順序、選擇、並行等方式來編排分佈式任務,Serverless 工作流會按照設定好的步驟可靠地協調任務執行,跟蹤每個步驟的狀態轉換,並在必要時執行用戶定義的重試邏輯,以確保工作流順利完成。Serverless 工作流通過提供日誌記錄和審計來監視工作流的執行,方便您輕鬆地診斷和調試應用。

image.png
image.png

您可以使用 Serverless 工作流編排一系列的函數資源,同時定義流程中每一步的輸入和輸出,使用內置控制步驟編排複雜邏輯、發起並行執行、管理超時或終止流程。另外通過控制檯能夠使用圖形界面顯示出執行任務狀態和執行順序,同時控制檯會顯示每個步驟的實時狀態,並提供每次執行的詳細歷史記錄。通過 Serverless 工作流 + 函數計算的組合,我們可以突破時間和空間的限制,對任意大小的視頻文件進行復雜的處理。

大視頻處理

簡單來講,處理一個大視頻的基本思路是:

1、將視頻先進行切片處理,把每一個分片的大小控制在合理的大小,以便單個函數計算實例可以對其進行快速處理。

2、拉起多個函數計算實例對每一個分片進行並行處理。

3、對處理結果進行合併。

通過 Serverless 工作流 + 函數計算進行視頻處理的流程如下:

image.png
通過 Serverless 工作流提供的可視界面,我們能在工作流執行的過程當中,方便的查看到每一個步驟運行的信息,並配合自定義的 Dashboard 實現對整套視頻處理系統的全面監控:

image.png

方案對比

image.png

總結

基於函數計算和 Serverless 工作流的彈性高可用視頻處理架構,充分體現了雲原生時代 Serverless 化思想,以事件驅動的形式觸發函數執行,真實計算資源真正意義上的按需使用。對於使用而言,這套方案在保證業務靈活度的同時,可以顯著降低維護成本與資源成本,並大幅度的縮短項目交付時間。

在線教育領域對於視頻處理的需求量非常大,而且對於處理速度、併發吞吐量、資源利用率等方面都有極高的要求,函數計算 + Serverless 工作流方案組合幫助用戶輕鬆建設彈性高可用的視頻處理架構,是實現這些複雜需求的最優解。隨著雲原生的不斷髮展, Serverless 相關技術還將深入更多的業務場景,有未來有無限可能!

Leave a Reply

Your email address will not be published. Required fields are marked *