背景 公司目前主要聚焦於視頻這個領域,利用視頻為媒體、文旅、會議等行業進行賦能。 既然聚焦於視頻領域,那麼視頻轉碼則是繞不開的話題。 為了降低成本,以及保證產品的核心能力,公司自建了一套轉碼系統。 轉碼服務除了儘可能多的相容業界的視頻格式外,轉碼的速度是另一個非常重要的指標。 因為視頻轉碼對用戶來說 ...
背景
公司目前主要聚焦於視頻這個領域,利用視頻為媒體、文旅、會議等行業進行賦能。
既然聚焦於視頻領域,那麼視頻轉碼則是繞不開的話題。
為了降低成本,以及保證產品的核心能力,公司自建了一套轉碼系統。
轉碼服務除了儘可能多的相容業界的視頻格式外,轉碼的速度是另一個非常重要的指標。
因為視頻轉碼對用戶來說,感知最強的就是視頻轉碼速度。
假如用戶上傳了一個1分鐘的視頻,轉碼花了10分鐘甚至更久的話,用戶肯定就不願意使用我們的產品了。
對於用戶來說等待的時間越短越好,對於轉碼服務來說轉碼速度越快越好。
我們先從轉碼流程說起,在聊一聊目前系統存在的問題,以及為serverless改造所做的努力。
轉碼流程
眾所周知,轉碼是CPU密集型任務,一個長視頻在單機上可能要轉很久。但如果能用儘可能利用多的CPU去進行轉碼,那麼轉碼速度將會大大加快。而現在豐富的雲產品能夠在短時間內提供大量的計算能力,以阿裡雲為例,阿裡雲提供了函數計算、Serverless應用引擎等serverless產品能夠支撐起我們所需要的計算能力。
於是為了提高轉碼倍速,我們將
- 視頻進行切片,每一個切片都是一個轉碼任務。一個長視頻經過切片以後就會被切分成大量轉碼子任務。
- 將轉碼子任務調度到不同的機器上執行,充分利用不同機器上的CPU資源,提高轉碼速度
- 當所有的轉碼子任務都執行完畢以後,再進行彙總合併輸出轉碼後的視頻
流程如下:
切片 轉碼 合併
輸入視頻 ------> (n個)轉碼任務 ------> (n個)轉碼結果 -----> 輸出視頻
改造前的系統架構
再來看看我們的系統架構。
之前轉碼服務是一個應用,同時肩負著調度和轉碼的職責,其中:
- 調度主要是跟MySQL、Redis打交道:用Redis維護任務隊列;MySQL則用來保存任務的執行狀態
- 轉碼則是執行任務:讀取文件系統中的源視頻,轉碼後再將視頻寫入到文件系統中
大規模集群面臨的問題
上面有提到為了提高轉碼速度,我們會有多個轉碼服務實例進行轉碼,但是上面的系統架構會限制轉碼集群的實例數。
上面的系統架構中,轉碼服務既承擔了轉碼職責,也承擔了調度的職責(獲取任務、以及更新任務狀態)。不符合存儲(Redis、MySQL等數據層)與計算分離,無法大規模快速獲取計算能力。
因為承擔了調度的職責就不可避免的要與Redis、MySQL打交道,啟動服務時就要與Redis、MySQL建立連接,且不說建立大量的連接Redis、MySQL能不能承受的住,光是建立連接所需要花費的時間就是一筆很大的浪費。
serverless改造
為了提供大規模的轉碼計算能力,我們決定對轉碼服務進行改造。
方案
改造的方案主要思路是將存儲與計算分離,說大白話就是講調度職責與轉碼職責進行分離,這樣就可以只對轉碼計算能力進行擴容。
這裡主要聊轉碼(計算)節點的改造點,主要有2個:
- 移除數據層的訪問操作(剝離調度服務能力),避免建立連接
- 優化啟動速度,儘可能縮短應用啟動時間
移除數據層的訪問操作
將轉碼(計算)節點的數據層訪問操作全部都移除後,如何與調度服務進行通信呢?比如獲取任務、提交轉碼結果需要通過調度服務訪問Redis和MySQL。
一般有2種選擇:dubbo或者http。我最終選擇使用http進行通信。
這裡先說一下為什麼沒有選擇dubbo:還是上面所提到的、需要建立連接的問題,如果使用dubbo,那麼就需要與zk等註冊中心建立連接。而且如果發生大規模上下線(如發佈)操作,那麼勢必給註冊中心帶來巨大的推送壓力。
選擇http進行通信,擺在眼前的第一個問題是:轉碼(計算)節點怎麼知道調度節點的訪問地址?
因為我們的服務部署在k8s集群中,藉助k8s內部功能變數名稱天然的解決了獲取調度節點訪問地址的問題。我們只需要訪問調度節點在k8s中內部功能變數名稱地址就可以訪問到調度節點介面,而無需關係發佈所帶來的ip變化等情況。
使用http進行通信,調度節點除了需要做好優雅下線,避免http請求被意外終止;還需要做好數據冪等的措施。
提高應用啟動速度
作為雲原生應用,不會常備很多計算資源,但是需要的時候希望馬上就有,這就要求應用啟動越快越好。
影響應用啟動速度的主要有下麵2點:
- 拉鏡像
- 應用啟動
拉鏡像的速度
我們選擇了阿裡雲 sae job作為serverless載體,sae job剛好有一個鏡像加速的能力:拉鏡像到啟動鏡像可以做到15s,還可以接受,這塊就不展開了。
應用啟動
這塊主要是儘可能的將非必須的代碼移除,減少springboot掃描的bean,目前啟動時間在6s左右。
另外也在嘗試使用graalvm編譯成本地可執行文件,測試的啟動時間約1s左右。因為涉及到SpringBoot大版本變更以及JDK版本變更,這個方案還在測試,沒有發佈到生產環境。
改造後的系統架構
效果
serverless改造後的轉碼服務,帶來的效果有2個:
- 帶來更高的轉碼速度:在面對大量轉碼也不用擔心轉碼慢的問題,一個字-擴!
- 成本的顯著降低:得益於按量付費的模式,只需要為實際使用的計算資源付費,無需預留計算資源。