Vimeo發(fā)布新轉(zhuǎn)碼基礎(chǔ)設(shè)施Falkor——降低成本的同時(shí)將速度推向極限。
Vimeo的下一代轉(zhuǎn)碼基礎(chǔ)設(shè)施Falkor現(xiàn)已登場(chǎng),標(biāo)志性的形象是充滿上個(gè)世紀(jì)80年代風(fēng)格的狗頭龍身。它不僅比前代方案更快、更可靠,也拉開(kāi)了通往云原生未來(lái)的序幕。關(guān)于Falkor的一切,本文將為您一一揭曉。
從歷史說(shuō)起
Falkor的前任方案是Tron轉(zhuǎn)碼技術(shù)棧,這套技術(shù)??梢宰匪莸?013年。Tron具有以下特點(diǎn):
?會(huì)將整個(gè)源文件下載到本地,將其轉(zhuǎn)碼為所需的profile,再將結(jié)果上傳至云存儲(chǔ)。
Tron是為前云時(shí)代的Vimeo所量身打造,當(dāng)時(shí)我們還在運(yùn)營(yíng)自己的數(shù)據(jù)中心(也配合使用一部分競(jìng)價(jià)實(shí)例以優(yōu)化運(yùn)營(yíng)成本)。但如今,我們已經(jīng)全面轉(zhuǎn)向Google Cloud。
盡管Tron已有10年歷史,但我們并不打算讓它徹底“退休”。某些Falkor無(wú)法處理的極端情況,還是要?jiǎng)赥ron的大駕。關(guān)于更多具體情況,我們將在后文中詳細(xì)介紹。
為什么選擇Falkor?
這套全新基礎(chǔ)設(shè)施的雛形發(fā)源于2011年,甚至比Tron的誕生還要早。但我們直到2019年底才在這個(gè)方向上全面發(fā)力,希望借Falkor項(xiàng)目達(dá)成以下幾個(gè)目標(biāo)。
將原始源文件直接作為輸入
這一點(diǎn)屬于對(duì)Tron開(kāi)發(fā)工作的延續(xù),希望盡可能使用原始源文件作為轉(zhuǎn)碼輸入,從而最大限度提升輸出質(zhì)量。畢竟夾層文件是轉(zhuǎn)碼的產(chǎn)物,而轉(zhuǎn)碼本身是個(gè)有損過(guò)程。所以跟直接使用原始源文件相比,使用夾層作為后續(xù)轉(zhuǎn)碼源會(huì)降低視頻質(zhì)量。
實(shí)現(xiàn)并行化和分布式轉(zhuǎn)碼
并行化與分布式轉(zhuǎn)碼的本質(zhì),就是把視頻拆分成一個(gè)個(gè)更小的片段,分別在我們的服務(wù)器上進(jìn)行轉(zhuǎn)碼。在完成所有轉(zhuǎn)碼之后,再把各片段組合起來(lái)以創(chuàng)建最終輸出(參見(jiàn)圖一)。這樣不僅轉(zhuǎn)碼速度更快,從錯(cuò)誤中恢復(fù)的能力也更強(qiáng)。
圖一:并行化和分布式轉(zhuǎn)碼過(guò)程。
我們希望新的基礎(chǔ)設(shè)施能繼續(xù)使用成本低廉的臨時(shí)競(jìng)價(jià)實(shí)例,延長(zhǎng)舊有Tron設(shè)施的使用周期。競(jìng)價(jià)實(shí)例不提供容量保證,但成本比按需實(shí)例低得多,價(jià)格普遍在后者的50%以下,也有助于對(duì)可用資源的快速變化做出響應(yīng)。在Vimeo的用例中,使用競(jìng)價(jià)實(shí)例意味著某些轉(zhuǎn)碼作業(yè)會(huì)被中途取消;但配合并行化與分布式轉(zhuǎn)碼,只需重新執(zhí)行一小部分即可順利完成視頻轉(zhuǎn)碼。
此外,Google等云服務(wù)商大多支持按秒(首分鐘之后)支付實(shí)例費(fèi)用。也就是說(shuō),運(yùn)行單一實(shí)例1個(gè)小時(shí)和運(yùn)行10個(gè)實(shí)例各6分鐘,其資源價(jià)格基本相當(dāng),但并行轉(zhuǎn)碼的總體耗時(shí)會(huì)短得多。
邁向云原生
之前提到,Tron是專為前云計(jì)算時(shí)代的Vimeo所設(shè)計(jì),那時(shí)候的云環(huán)境還有很多問(wèn)題,所以立足本地基礎(chǔ)設(shè)施是個(gè)非常合乎邏輯的選擇。但現(xiàn)在既然決定上云,我們當(dāng)然要充分利用云服務(wù)商提供的方案。這樣能大大削減需要自主管理的本地基礎(chǔ)設(shè)施,但代價(jià)就是我們得提防別陷入供應(yīng)商鎖定的陷阱。一旦過(guò)度依賴當(dāng)前云服務(wù)商的復(fù)雜技術(shù)體系,那么我們后續(xù)會(huì)很難遷移至其他云服務(wù)商。
盡可能使用競(jìng)價(jià)實(shí)例
如前所述,使用競(jìng)價(jià)實(shí)例有助于降低成本,同時(shí)不會(huì)顯著影響轉(zhuǎn)碼時(shí)間。
將音頻和視頻分別存儲(chǔ),生成碎片化的MP4輸出
將音頻和視頻分別輸出,讓我們得以輕松訪問(wèn)音頻和視頻流。
如果音頻只需要被提取和存儲(chǔ)一次(而非與視頻混合或合并),那我們的打包壓力就會(huì)小得多,也能節(jié)約存儲(chǔ)成本。(傳統(tǒng)上,音頻和視頻會(huì)被存儲(chǔ)在同一文件內(nèi),導(dǎo)致不同視頻質(zhì)量或還原度版本中都要單獨(dú)保存一份音頻。)
使用碎片化視頻,我們可以輕松將視頻文件切割成多個(gè)片段,這種存儲(chǔ)方式能降低打包程序的運(yùn)行難度。
但這里也有新的權(quán)衡,音頻與視頻拆分會(huì)提高漸進(jìn)式文件的交付難度,挑戰(zhàn)我們將音視頻即時(shí)合并的能力。
使用標(biāo)準(zhǔn)工具進(jìn)行開(kāi)發(fā)和部署
為團(tuán)隊(duì)和公司內(nèi)其他部門(mén)提供一組類似的工具(語(yǔ)言、庫(kù)、編排等)服務(wù),確保我們的基礎(chǔ)設(shè)施更易于維護(hù)、充分發(fā)揮其他服務(wù)和團(tuán)隊(duì)的產(chǎn)出成果,從整體上降低設(shè)施復(fù)雜性。
Tron仍依賴于Python 2等已被棄用的技術(shù)。
Falkor宏觀架構(gòu)解析
下面,我們用圖文詳解的方式聊聊Falkor的宏觀架構(gòu)。圖二所示,為Falkor各組件與其他服務(wù)間的交互關(guān)系。
圖二:Falkor組件。
圖三所示,為Falkor作業(yè)的端到端流程。
圖三:Falkor流程圖。
下面是Falkor的具體轉(zhuǎn)碼步驟。
步驟1
客戶端通知我們的視頻API使用profile集列表,對(duì)視頻數(shù)據(jù)進(jìn)行轉(zhuǎn)碼。Profile集的確切列表視具體用例而定。例如,并非所有視頻都可使用AV1格式。
步驟2
我們的視頻API會(huì)執(zhí)行一系列檢查,包括獲取視頻源位置、要求Falkor API運(yùn)行分析作業(yè)等。檢查會(huì)返回元數(shù)據(jù),包括視頻時(shí)長(zhǎng)、編解碼器、幀率、視頻是否為HDR等。這些元數(shù)據(jù)將被放入云存儲(chǔ),以供后續(xù)轉(zhuǎn)碼作業(yè)重復(fù)使用。
步驟3
視頻API從分析作業(yè)處接收元數(shù)據(jù),并確定需要運(yùn)行哪些轉(zhuǎn)碼音頻和視頻profile:使用哪些分辨率、是否啟用HDR等。這些profile各自擁有對(duì)應(yīng)的新Falkkor API作業(yè)。
音頻作業(yè)在音頻轉(zhuǎn)碼工作器上運(yùn)行,該工作器負(fù)責(zé)對(duì)源音頻進(jìn)行轉(zhuǎn)碼,而非在本地下載再將轉(zhuǎn)碼結(jié)果上傳至云端。
視頻作業(yè)稍微復(fù)雜一些。根據(jù)用戶所上傳源視頻的索引和其他元數(shù)據(jù),F(xiàn)alkor API將確定視頻的拆分位置,理想狀態(tài)下是分割成時(shí)長(zhǎng)約1分鐘的片段。如果無(wú)法分割視頻,則回退至Tron對(duì)源視頻做整體處理(后文將討論具體細(xì)節(jié))。每個(gè)片段均由各視頻轉(zhuǎn)碼工作器做并行轉(zhuǎn)碼,根據(jù)由源文件分配的視頻片段獲取所需的字節(jié)范圍,之后將結(jié)果上傳至云存儲(chǔ)。
當(dāng)所有片段均處理完成后,F(xiàn)alkor API會(huì)創(chuàng)建最終的合并作業(yè)。該作業(yè)會(huì)根據(jù)各片段的標(biāo)題頭生成視頻標(biāo)題頭,例如moov和SIDX,再將此標(biāo)題頭與所有片段連接起來(lái),最后將合并完成的視頻存儲(chǔ)在目標(biāo)位置。在我們的云服務(wù)環(huán)境下,只需調(diào)用云存儲(chǔ)API即可完成最后一步(詳見(jiàn)下文)。
步驟4
以上步驟完成后,F(xiàn)alkor AIP會(huì)告知視頻API工作已完成。視頻API將新的音頻或視頻文件添加至視頻管理系統(tǒng),再將完成消息通知客戶端。
每個(gè)單獨(dú)作業(yè)都有自己的通知過(guò)程,可幫助客戶決定如何按業(yè)務(wù)邏輯采取行動(dòng)。例如,客戶端允許在H.264視頻組件之一和AAC音頻組件之一準(zhǔn)備就緒后,立即開(kāi)始播放視頻;或者,客戶端也可以等待所有轉(zhuǎn)碼均完成后再行播放。客戶端還可觸發(fā)其他處理任務(wù),例如為視頻內(nèi)容生成縮略圖。
技術(shù)細(xì)節(jié)
從技術(shù)棧的角度看,所有作業(yè)均在Google Cloud三個(gè)美國(guó)區(qū)域的Kubernetes(GKE)上運(yùn)行。在隊(duì)列方面,我們使用的是PubSub。Falkor本身由Go編寫(xiě),轉(zhuǎn)碼器則用C語(yǔ)言編寫(xiě)。
Falkor還用到了我們的作業(yè)調(diào)度程序Quickset,讓我們能夠通過(guò)以下兩種方式降低成本:
?能在可用的CPU和內(nèi)存資源范圍之內(nèi),有效將任務(wù)分配給各工作器,在盡可能減少CPU閑置的同時(shí)、仍為突發(fā)事件保留一部分空間。
?能夠自動(dòng)縮放Kubernetes節(jié)點(diǎn),并根據(jù)競(jìng)價(jià)實(shí)例優(yōu)先級(jí)做任務(wù)安排,保證只在真正必要時(shí)才回退至非競(jìng)價(jià)實(shí)例。
但要讓Quickset有效分配任務(wù),必須保證各項(xiàng)任務(wù)的時(shí)長(zhǎng)和所需的資源量大致相同。為了實(shí)現(xiàn)這一點(diǎn),我們將任務(wù)排入不同隊(duì)列。任務(wù)分析主要根據(jù)大小進(jìn)行,因?yàn)槲覀冋也坏礁玫慕浦颠x項(xiàng)。音頻任務(wù)按持續(xù)時(shí)間和編解碼器做分析,這是因?yàn)槲覀儾粫?huì)對(duì)音頻做片段拆分,所以不同文件的持續(xù)時(shí)長(zhǎng)會(huì)有很大變化。視頻任務(wù)則按還原度和編解碼器劃分,因?yàn)橐曨l片段的持續(xù)時(shí)間是恒定的,每段大約一分鐘。
發(fā)布流程
我們?cè)谡麄€(gè)發(fā)布過(guò)程中始終小心謹(jǐn)慎。畢竟在快速迭代的同時(shí),我們也要保證盡量減少對(duì)用戶體驗(yàn)的干擾。
我們首先將一小部分H.264 240p轉(zhuǎn)碼發(fā)送至新基礎(chǔ)設(shè)施,原因如下:
?這種還原度的視頻不會(huì)通過(guò)UI或API向用戶公開(kāi),僅面向內(nèi)部播放器或外部播放列表,所以即使出現(xiàn)問(wèn)題也不會(huì)造成太大影響。
?我們可以借此引導(dǎo)流量并調(diào)整比例,不必?fù)?dān)心突然對(duì)用戶造成嚴(yán)重影響。
?我們可以在此期間構(gòu)建并集成零散的音頻和視頻數(shù)據(jù)管線,借此重新組合漸進(jìn)式文件。
我們還做了一些微小調(diào)整,修復(fù)了一些bug并解決了縮放問(wèn)題。當(dāng)240p視頻全部由新基礎(chǔ)設(shè)施承載之后,我們開(kāi)始向其發(fā)送AAC和Opus格式的音頻,意味著Falkor開(kāi)始處理部分實(shí)際業(yè)務(wù)流量。
之后我們轉(zhuǎn)向H.264 1080p,這種還原度的視頻能讓我們輕松驗(yàn)證視覺(jué)質(zhì)量是否符合預(yù)期,也是用戶使用最多的視頻格式。萬(wàn)一出現(xiàn)問(wèn)題,我們會(huì)很快得到反饋。雖然我們?cè)趦?nèi)部做了一遍又一遍測(cè)試,但每當(dāng)實(shí)際處理用戶上傳的內(nèi)容時(shí),總會(huì)冒出意料之外的有趣極端案例。
在1080p之后,我們對(duì)新基礎(chǔ)設(shè)施的規(guī)模伸縮和輸出質(zhì)量已經(jīng)充滿信心,于是決定引入全部其他H.264格式:4K、2K、720p、360p等,后續(xù)還將轉(zhuǎn)移360o視頻和用于HDR10及杜比視界的HEVC視頻。
但在撰寫(xiě)本文的同時(shí),我們還有不少轉(zhuǎn)碼任務(wù)沒(méi)有遷往Falkor:
?具有可變幀率源的視頻。我們打算暫時(shí)擱置這部分極端案例,等到之后能輕松發(fā)現(xiàn)幀率問(wèn)題時(shí)再遷移比較安全。
?AV1。其實(shí)這里沒(méi)有任何技術(shù)障礙,我們只是不想過(guò)于貪多。除了極少數(shù)內(nèi)部精選的視頻外,我們還沒(méi)有遷移AV1。事實(shí)也證明,這種格式確實(shí)需要投入更多精力來(lái)整理。
?在網(wǎng)絡(luò)上存量較少的源視頻。對(duì)這部分視頻,我們還是采取將源文件下載到磁盤(pán)上的老辦法。
升級(jí)總結(jié)
我得說(shuō),這項(xiàng)工作推進(jìn)得相當(dāng)順利。當(dāng)然,期間也出現(xiàn)了一些與視頻相關(guān)的bug(我們已經(jīng)向上游發(fā)布了相關(guān)補(bǔ)丁)和基礎(chǔ)設(shè)施問(wèn)題。
首先,我們需要在單獨(dú)的Kubernetes集群中運(yùn)行AIP和工作器。這是因?yàn)橐坏┘褐械墓?jié)點(diǎn)超過(guò)1000個(gè),GKE Ingress就無(wú)法工作。但現(xiàn)在這個(gè)限制已經(jīng)解除了。
第二,Google Cloud的VPC原生集群中,每個(gè)pod都有自己的IP地址。而且因?yàn)槲覀冇泻芏嗪芏鄍od,所以不想把這個(gè)集群與Vimeo的其余基礎(chǔ)設(shè)施并列部署,畢竟我們已經(jīng)占用了太多的10.x.x.x內(nèi)部IP資源。但我們將Cloud NAT設(shè)置為仍能與基礎(chǔ)設(shè)施的其余部分通信,例如我們的可觀察性服務(wù)。
第三,我們的一部分狀態(tài)機(jī)無(wú)法妥善處理重復(fù)消息。Google Cloud的Pub/Sub提供“at-least-once”(至少一次)交付保證,但并非“exactly-once”(嚴(yán)格一次)。所以我們被迫重寫(xiě)了一些代碼塊以使其更具彈性,并會(huì)在后續(xù)編寫(xiě)新代碼時(shí)考慮到這個(gè)問(wèn)題。
第四,為了保證可用性,我們?cè)诿绹?guó)三個(gè)區(qū)域同時(shí)運(yùn)行,所以拉高了出口成本。
升級(jí)的回報(bào)
簡(jiǎn)單來(lái)講:成本下降、速度加快。在類似的用例下,F(xiàn)alkor的運(yùn)營(yíng)成本遠(yuǎn)低于Tron,而且我們還有更進(jìn)一步的調(diào)優(yōu)空間。
此外,雖然Falkor并沒(méi)有解決所有問(wèn)題(短視頻的轉(zhuǎn)碼方式和用時(shí)仍跟過(guò)去一樣),但長(zhǎng)視頻的轉(zhuǎn)碼速度確實(shí)大大加快。用戶們紛紛給出好評(píng),所以我們的“折騰”也就物有所值了。
審核編輯:劉清
-
python
+關(guān)注
關(guān)注
56文章
4792瀏覽量
84627 -
視頻流解碼
+關(guān)注
關(guān)注
0文章
2瀏覽量
6183 -
Vimeo
+關(guān)注
關(guān)注
0文章
4瀏覽量
7997
原文標(biāo)題:Vimeo的轉(zhuǎn)碼設(shè)施升級(jí)之旅
文章出處:【微信號(hào):livevideostack,微信公眾號(hào):LiveVideoStack】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論