背景
公司目前主要聚焦於影片這個領域,利用影片為媒體、文旅、會議等行業進行賦能。
既然聚焦於影片領域,那麼影片轉碼則是繞不開的話題。
為了降低成本,以及保證產品的核心能力,公司自建了一套轉碼系統。
轉碼服務除了儘可能多的相容業界的影片格式外,轉碼的速度是另一個非常重要的指標。
因為影片轉碼對使用者來說,感知最強的就是影片轉碼速度。
假如使用者上傳了一個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個:
- 帶來更高的轉碼速度:在面對大量轉碼也不用擔心轉碼慢的問題,一個字-擴!
- 成本的顯著降低:得益於按量付費的模式,只需要為實際使用的計算資源付費,無需預留計算資源。