轉碼服務serverless探索

那只是一股逆流發表於2023-03-01

背景

公司目前主要聚焦於影片這個領域,利用影片為媒體、文旅、會議等行業進行賦能。
既然聚焦於影片領域,那麼影片轉碼則是繞不開的話題。
為了降低成本,以及保證產品的核心能力,公司自建了一套轉碼系統。

轉碼服務除了儘可能多的相容業界的影片格式外,轉碼的速度是另一個非常重要的指標。
因為影片轉碼對使用者來說,感知最強的就是影片轉碼速度。
假如使用者上傳了一個1分鐘的影片,轉碼花了10分鐘甚至更久的話,使用者肯定就不願意使用我們的產品了。
對於使用者來說等待的時間越短越好,對於轉碼服務來說轉碼速度越快越好。

我們先從轉碼流程說起,在聊一聊目前系統存在的問題,以及為serverless改造所做的努力。

轉碼流程

眾所周知,轉碼是CPU密集型任務,一個長影片在單機上可能要轉很久。但如果能用盡可能利用多的CPU去進行轉碼,那麼轉碼速度將會大大加快。而現在豐富的雲產品能夠在短時間內提供大量的計算能力,以阿里云為例,阿里雲提供了函式計算、Serverless應用引擎等serverless產品能夠支撐起我們所需要的計算能力。
於是為了提高轉碼倍速,我們將

  1. 影片進行切片,每一個切片都是一個轉碼任務。一個長影片經過切片以後就會被切分成大量轉碼子任務。
  2. 將轉碼子任務排程到不同的機器上執行,充分利用不同機器上的CPU資源,提高轉碼速度
  3. 當所有的轉碼子任務都執行完畢以後,再進行彙總合併輸出轉碼後的影片

流程如下:


         切片                  轉碼                  合併
輸入影片 ------> (n個)轉碼任務 ------> (n個)轉碼結果 -----> 輸出影片


改造前的系統架構

再來看看我們的系統架構。

之前轉碼服務是一個應用,同時肩負著排程和轉碼的職責,其中:

  1. 排程主要是跟MySQL、Redis打交道:用Redis維護任務佇列;MySQL則用來儲存任務的執行狀態
  2. 轉碼則是執行任務:讀取檔案系統中的源影片,轉碼後再將影片寫入到檔案系統中

改造前的系統架構

大規模叢集面臨的問題

上面有提到為了提高轉碼速度,我們會有多個轉碼服務例項進行轉碼,但是上面的系統架構會限制轉碼叢集的例項數。

上面的系統架構中,轉碼服務既承擔了轉碼職責,也承擔了排程的職責(獲取任務、以及更新任務狀態)。不符合儲存(Redis、MySQL等資料層)與計算分離,無法大規模快速獲取計算能力。

因為承擔了排程的職責就不可避免的要與Redis、MySQL打交道,啟動服務時就要與Redis、MySQL建立連線,且不說建立大量的連線Redis、MySQL能不能承受的住,光是建立連線所需要花費的時間就是一筆很大的浪費。

serverless改造

為了提供大規模的轉碼計算能力,我們決定對轉碼服務進行改造。

方案

改造的方案主要思路是將儲存與計算分離,說大白話就是講排程職責與轉碼職責進行分離,這樣就可以只對轉碼計算能力進行擴容。
這裡主要聊轉碼(計算)節點的改造點,主要有2個:

  1. 移除資料層的訪問操作(剝離排程服務能力),避免建立連線
  2. 最佳化啟動速度,儘可能縮短應用啟動時間

移除資料層的訪問操作

將轉碼(計算)節點的資料層訪問操作全部都移除後,如何與排程服務進行通訊呢?比如獲取任務、提交轉碼結果需要透過排程服務訪問Redis和MySQL。
一般有2種選擇:dubbo或者http。我最終選擇使用http進行通訊。

這裡先說一下為什麼沒有選擇dubbo:還是上面所提到的、需要建立連線的問題,如果使用dubbo,那麼就需要與zk等註冊中心建立連線。而且如果發生大規模上下線(如釋出)操作,那麼勢必給註冊中心帶來巨大的推送壓力。

選擇http進行通訊,擺在眼前的第一個問題是:轉碼(計算)節點怎麼知道排程節點的訪問地址?
因為我們的服務部署在k8s叢集中,藉助k8s內部域名天然的解決了獲取排程節點訪問地址的問題。我們只需要訪問排程節點在k8s中內部域名地址就可以訪問到排程節點介面,而無需關係釋出所帶來的ip變化等情況。

使用http進行通訊,排程節點除了需要做好優雅下線,避免http請求被意外終止;還需要做好資料冪等的措施。

提高應用啟動速度

作為雲原生應用,不會常備很多計算資源,但是需要的時候希望馬上就有,這就要求應用啟動越快越好。
影響應用啟動速度的主要有下面2點:

  1. 拉映象
  2. 應用啟動

拉映象的速度

我們選擇了阿里雲 sae job作為serverless載體,sae job剛好有一個映象加速的能力:拉映象到啟動映象可以做到15s,還可以接受,這塊就不展開了。

應用啟動

這塊主要是儘可能的將非必須的程式碼移除,減少springboot掃描的bean,目前啟動時間在6s左右。
另外也在嘗試使用graalvm編譯成本地可執行檔案,測試的啟動時間約1s左右。因為涉及到SpringBoot大版本變更以及JDK版本變更,這個方案還在測試,沒有釋出到生產環境。

改造後的系統架構

改造後的系統架構

效果

serverless改造後的轉碼服務,帶來的效果有2個:

  1. 帶來更高的轉碼速度:在面對大量轉碼也不用擔心轉碼慢的問題,一個字-擴!
  2. 成本的顯著降低:得益於按量付費的模式,只需要為實際使用的計算資源付費,無需預留計算資源。

相關文章