公司目前主要聚焦於視訊這個領域,利用視訊為媒體、文旅、會議等行業進行賦能。
既然聚焦於視訊領域,那麼視訊轉碼則是繞不開的話題。
為了降低成本,以及保證產品的核心能力,公司自建了一套轉碼系統。
轉碼服務除了儘可能多的相容業界的視訊格式外,轉碼的速度是另一個非常重要的指標。
因為視訊轉碼對使用者來說,感知最強的就是視訊轉碼速度。
假如使用者上傳了一個1分鐘的視訊,轉碼花了10分鐘甚至更久的話,使用者肯定就不願意使用我們的產品了。
對於使用者來說等待的時間越短越好,對於轉碼服務來說轉碼速度越快越好。
我們先從轉碼流程說起,在聊一聊目前系統存在的問題,以及為serverless改造所做的努力。
眾所周知,轉碼是CPU密集型任務,一個長視訊在單機上可能要轉很久。但如果能用盡可能利用多的CPU去進行轉碼,那麼轉碼速度將會大大加快。而現在豐富的雲產品能夠在短時間內提供大量的計算能力,以阿里云為例,阿里雲提供了函數計算、Serverless應用引擎等serverless產品能夠支撐起我們所需要的計算能力。
於是為了提高轉碼倍速,我們將
流程如下:
切片 轉碼 合併
輸入視訊 ------> (n個)轉碼任務 ------> (n個)轉碼結果 -----> 輸出視訊
再來看看我們的系統架構。
之前轉碼服務是一個應用,同時肩負著排程和轉碼的職責,其中:
上面有提到為了提高轉碼速度,我們會有多個轉碼服務範例進行轉碼,但是上面的系統架構會限制轉碼叢集的範例數。
上面的系統架構中,轉碼服務既承擔了轉碼職責,也承擔了排程的職責(獲取任務、以及更新任務狀態)。不符合儲存(Redis、MySQL等資料層)與計算分離,無法大規模快速獲取計算能力。
因為承擔了排程的職責就不可避免的要與Redis、MySQL打交道,啟動服務時就要與Redis、MySQL建立連線,且不說建立大量的連線Redis、MySQL能不能承受的住,光是建立連線所需要花費的時間就是一筆很大的浪費。
為了提供大規模的轉碼計算能力,我們決定對轉碼服務進行改造。
改造的方案主要思路是將儲存與計算分離,說大白話就是講排程職責與轉碼職責進行分離,這樣就可以只對轉碼計算能力進行擴容。
這裡主要聊轉碼(計算)節點的改造點,主要有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個: