短視頻系統(tǒng)核心模塊:視頻上傳與轉(zhuǎn)碼全流程解析
上周在等電梯時,發(fā)現(xiàn)在 4G 網(wǎng)絡(luò)或者無網(wǎng)絡(luò)的情況下,抖音、B 站的視頻依舊可以正常觀看,在視頻發(fā)布時,甚至可以做到無網(wǎng)卡頓 ——> 連網(wǎng)續(xù)傳的無縫連接操作。
于是,又想起了曾經(jīng)在某視頻平臺的面試經(jīng)歷。
引言
面試官:“在抖音、快手這類億級日活平臺,用戶輕點(diǎn) 發(fā)布 的背后,藏著視頻上傳與轉(zhuǎn)碼的 生死時速 —— 這倆看似簡單的 傳文件、改格式 操作,直接決定了用戶是 秒發(fā)秒看 還是 怒刪 APP。
聽說你對視頻傳輸和轉(zhuǎn)碼有一定研究,那簡單說下短視頻的上傳轉(zhuǎn)碼流程吧!”
今天小?就帶著零星的面試記憶,帶著大家扒一扒短視頻上傳轉(zhuǎn)碼的全流程:從時序圖理清組件協(xié)作,到拆解決策邏輯、優(yōu)化技巧,手把手帶你體驗(yàn)一套又穩(wěn)又快的視頻生產(chǎn)鏈路。
一、視頻上傳與轉(zhuǎn)碼整體時序圖
便于大家理解,我畫了個時序圖。要理解整個流程,首先得看清各組件之間的協(xié)作關(guān)系。
以下時序圖覆蓋了從 “客戶端發(fā)起上傳” 到 “轉(zhuǎn)碼完成入庫” 的全鏈路,涉及客戶端、API 網(wǎng)關(guān)、上傳服務(wù)等 7 類核心組件,每一步都標(biāo)注了關(guān)鍵技術(shù)選型和數(shù)據(jù)流向,讓你一目了然。
圖片
可惜當(dāng)時是線上面試,時序圖顯然來不及準(zhǔn)備了,于是我口述了下面的內(nèi)容。
1. 客戶端發(fā)起上傳請求,獲取分片上傳憑證(對應(yīng)時序圖 1-6 步)
圖片
1.1 涉及模塊及作用
- Client(客戶端):用戶操作的入口(如抖音 APP),核心作用是收集視頻元數(shù)據(jù)(大小、格式、整體 MD5),并向網(wǎng)關(guān)發(fā)起 “申請分片上傳” 的請求 —— 這一步是為了避免直接上傳大文件時的風(fēng)險,先拿到 “上傳許可”。
- APIGW(API 網(wǎng)關(guān)):系統(tǒng)的 “入口守衛(wèi)”,作用是統(tǒng)一接收客戶端請求,先做兩件關(guān)鍵事:①鑒權(quán)(驗(yàn)證用戶 Token 是否有效,防止非法上傳);②限流(比如限制單個用戶每秒最多發(fā)起 2 次上傳請求,避免惡意刷量),之后再將請求轉(zhuǎn)發(fā)給上傳服務(wù)。
- UploadSvc(上傳服務(wù)):上傳流程的 “協(xié)調(diào)者”,不直接存儲視頻,而是負(fù)責(zé)與對象存儲交互,申請 “分片上傳憑證(UploadId)”——UploadId 是對象存儲分配的唯一標(biāo)識,用于后續(xù)分片上傳、合并的身份驗(yàn)證,避免不同用戶的分片混淆。
- OSS(對象存儲):視頻分片的 “臨時倉庫”,作用是生成并返回 UploadId 和分片編號范圍(比如 1-10 片,對應(yīng) 10MB 視頻按 1MB 拆分),同時提供后續(xù)分片上傳的接口地址。
1.2 交互邏輯與設(shè)計(jì)原因
這時,面試官針對細(xì)節(jié)發(fā)問了:“為什么客戶端不直接調(diào)用 OSS,而是要通過 API 網(wǎng)關(guān)和上傳服務(wù)?”
我心想,這不是小 case 嘛:“如果客戶端直接對接 OSS,會暴露 OSS 的訪問密鑰,存在數(shù)據(jù)泄露風(fēng)險。
通過網(wǎng)關(guān)和上傳服務(wù)中轉(zhuǎn),既能統(tǒng)一鑒權(quán)、限流,又能隱藏后端存儲細(xì)節(jié),后續(xù)切換存儲服務(wù)商(如從阿里云 OSS 換成騰訊云 COS)時,客戶端無需修改代碼?!?/p>
“那為什么要先申請 UploadId 呢?”
“分片上傳是 分多次傳碎片,UploadId 相當(dāng)于碎片的歸屬標(biāo)識—— 只有攜帶正確 UploadId 的分片,OSS 才會認(rèn)為是同一視頻的碎片,后續(xù)才能合并成完整文件,避免不同視頻的分片混在一起?!?/p>
這時,面試官微微點(diǎn)了點(diǎn)頭,“好,你接著往下說?!?/p>
2. 客戶端分片上傳視頻數(shù)據(jù)(對應(yīng)時序圖 7-8 步,循環(huán)執(zhí)行)
圖片
2.1 涉及模塊及作用
- Client(客戶端):按 1MB / 片拆分視頻,并發(fā)發(fā)起分片上傳請求(每次傳 1 個分片,攜帶 UploadId、分片號、分片數(shù)據(jù))—— 并發(fā)上傳是為了提速,比如同時傳 3 個分片,比一個一個傳快 2-3 倍。
- OSS(對象存儲):接收并存儲單個分片,校驗(yàn)分片的完整性(比如通過分片 MD5),之后返回 “ETag 值”——ETag 是分片的唯一標(biāo)識,相當(dāng)于 “碎片的簽收單”,客戶端后續(xù)需要用 ETag 證明 “這個分片已傳成功”。
這時,面試官又問了:“這個 ETag 有啥作用呢?”
我心想,就猜到你會這么問:當(dāng)然是為了 數(shù)據(jù)一致性校驗(yàn)了,客戶端后續(xù)通知 “上傳完成” 時,會把所有分片的 ETag 列表傳給上傳服務(wù),上傳服務(wù)再拿給 OSS——OSS 會對比自己存儲的分片 ETag 和客戶端上報的 ETag,只有全部一致,才會執(zhí)行合并,避免分片丟失或損壞。
3. 客戶端完成上傳,觸發(fā)分片合并(對應(yīng)時序圖 9-15 步)
圖片
當(dāng)我說完上面的流程時,面試官心想,有點(diǎn)意思,不過面上也不能表現(xiàn)出來。于是繼續(xù)發(fā)問:“為什么要通過 Kafka 發(fā)轉(zhuǎn)碼任務(wù),而不是上傳服務(wù)直接調(diào)用轉(zhuǎn)碼服務(wù)?”
“這個是很常見的消息中間件的作用,就是避免 服務(wù)耦合 和 單點(diǎn)故障:如果上傳服務(wù)直接調(diào)用轉(zhuǎn)碼服務(wù),轉(zhuǎn)碼服務(wù)宕機(jī)時,上傳服務(wù)會被阻塞,甚至拖垮?!?/p>
用 Kafka 做中間件,上傳服務(wù)發(fā)完消息就 “解脫”,轉(zhuǎn)碼服務(wù)恢復(fù)后可以繼續(xù)消費(fèi)任務(wù),不會丟失;同時,后續(xù)增加多個轉(zhuǎn)碼節(jié)點(diǎn)時,只需讓它們共同消費(fèi) Kafka 的任務(wù),就能實(shí)現(xiàn)負(fù)載均衡。
4. 轉(zhuǎn)碼服務(wù)消費(fèi)任務(wù),處理多碼率轉(zhuǎn)碼(對應(yīng)時序圖 16-20 步)
圖片
4.1 涉及模塊及作用
- TranscodeSvc(轉(zhuǎn)碼服務(wù)):從 Kafka 中消費(fèi)轉(zhuǎn)碼任務(wù)(按優(yōu)先級拉取,熱門用戶任務(wù)優(yōu)先),先通過 OSS SDK 讀取視頻源文件,再調(diào)用 FFmpeg 工具進(jìn)行多碼率轉(zhuǎn)碼 —— 轉(zhuǎn)碼的核心是 “適配不同網(wǎng)絡(luò)環(huán)境”,比如 480P 給弱網(wǎng)用戶,1080P 給 5G 用戶。
講到這里,面試官才微微點(diǎn)頭,看來是有實(shí)踐過的。于是問了一個影響實(shí)際體驗(yàn)的問題:
4.2 為什么要按優(yōu)先級拉取任務(wù)?
這個問題很簡單,無非就是系統(tǒng)中場景的熱 key 問題。
關(guān)鍵在于保障 “核心用戶體驗(yàn)”:熱門用戶(如粉絲 10 萬 + 的創(chuàng)作者)的視頻上線速度很重要,若和普通用戶的任務(wù)一起排隊(duì),可能會延遲很久,影響創(chuàng)作者積極性。按優(yōu)先級排序后,熱門用戶的任務(wù)先處理,普通用戶的任務(wù)后續(xù)處理,平衡 “核心需求” 和 “普通需求”。
4.3 那為什么要同時轉(zhuǎn) 480P/720P/1080P 多碼率呢?
主要是適配 “多樣化網(wǎng)絡(luò)與設(shè)備”:用戶的網(wǎng)絡(luò)環(huán)境差異大(2G/3G/4G/5G/WiFi),設(shè)備屏幕分辨率也不同(手機(jī) / 平板 / 電腦)—— 弱網(wǎng)用戶用 480P,播放不卡頓;高速網(wǎng)絡(luò)用戶用 1080P,體驗(yàn)高清;多碼率并存,能讓不同場景的用戶都有好體驗(yàn)。
5. 轉(zhuǎn)碼完成,寫入 CDN 源站,更新元數(shù)據(jù)(對應(yīng)時序圖 21-25 步)
圖片
5.1 涉及模塊及作用
- CDNSource(CDN 源站):存儲轉(zhuǎn)碼后的視頻文件,后續(xù)會同步到全國的 CDN 節(jié)點(diǎn)(如北京、上海、廣州的節(jié)點(diǎn))—— 用戶播放視頻時,會從就近的 CDN 節(jié)點(diǎn)拉取,減少延遲(比如廣州用戶從廣州節(jié)點(diǎn)拉取,比從北京源站拉取快 1-2 秒)。
- Kafka(消息隊(duì)列):接收上傳服務(wù)發(fā)送的 “審核任務(wù)消息”—— 視頻上線前必須審核(防止違規(guī)內(nèi)容),通過 Kafka 轉(zhuǎn)發(fā)審核任務(wù),讓審核服務(wù)異步處理,不阻塞上傳服務(wù)的后續(xù)操作。
5.2 為什么要把視頻放到 CDN,而不是直接從 OSS 播放?
降低 “源站壓力” 和 “用戶延遲”:如果所有用戶都從 OSS 拉取視頻,OSS 的帶寬壓力會極大,且跨地域訪問延遲高(如新疆用戶訪問北京 OSS,延遲可能 100ms+);CDN 有全國節(jié)點(diǎn),用戶就近訪問,延遲低(通常 20-50ms),且 CDN 能緩存熱門視頻,減少對 OSS 的請求,降低整體成本。
講到這里,我感覺面試官還沒想好接下來的問題,于是又補(bǔ)充了一下,做個小小的總結(jié)。
6. 整個流程背后的核心設(shè)計(jì)思想
上述整個時序圖的交互邏輯,圍繞三個核心目標(biāo)展開:
- 可靠性:通過分片上傳、ETag 校驗(yàn)、任務(wù)重試,確保視頻數(shù)據(jù)不丟失、不損壞;
- 效率性:通過并發(fā)上傳、GPU 轉(zhuǎn)碼、CDN 分發(fā),讓視頻上傳快、轉(zhuǎn)碼快、播放快;
- 可擴(kuò)展性:通過 API 網(wǎng)關(guān)、消息隊(duì)列、微服務(wù)拆分(上傳 / 轉(zhuǎn)碼 / 審核獨(dú)立),后續(xù)增加節(jié)點(diǎn)、切換組件(如換 OSS、換 CDN)時,系統(tǒng)能靈活應(yīng)對,支撐業(yè)務(wù)增長(從百萬級用戶到億級用戶)。
理解這些模塊作用和交互邏輯,就能掌握短視頻上傳與轉(zhuǎn)碼的核心設(shè)計(jì)思路,后續(xù)遇到類似場景(如大文件上傳、音視頻處理),也能復(fù)用這些技術(shù)方案。
二、關(guān)鍵技術(shù)細(xì)節(jié)拆解
這時,面試官調(diào)整了下坐姿,說:“嗯,那你再說說分片上傳的設(shè)計(jì)吧”。
看到這里,想必大家和面試官一樣,都已經(jīng)了解了視頻上傳的大概。于是我們再深入每個環(huán)節(jié)的技術(shù)核心,解決實(shí)際開發(fā)中可能遇到的 “坑”。
1. 分片上傳的核心設(shè)計(jì):解決 “大文件上傳失敗” 問題
短視頻文件通常在 10-50MB 之間,若采用 “一次性上傳”,一旦遇到網(wǎng)絡(luò)波動,就可能導(dǎo)致全量重傳,用戶體驗(yàn)極差。
分片上傳通過三大設(shè)計(jì),從根本上解決這一問題:
1.1 分片大小選擇
我們采用 1MB / 片的規(guī)格,這是兼顧并發(fā)效率與對象存儲接口限制的最優(yōu)解。
以阿里云 OSS 為例,單分片最大支持 5GB,但小分片更易重試 —— 哪怕某一個 1MB 的分片上傳失敗,重新上傳也只需幾秒,而非整個幾十 MB 的視頻。
1.2 斷點(diǎn)續(xù)傳
客戶端會記錄每一個已成功上傳分片的 ETag(對象存儲返回的唯一標(biāo)識),下次上傳同一視頻時,只需對比本地分片 MD5 與 OSS 中的 ETag,僅重新上傳未成功的分片。
比如用戶上傳到一半退出 APP,再次打開時,系統(tǒng)能自動續(xù)傳剩余分片,無需從頭開始。
1.3 數(shù)據(jù)一致性校驗(yàn)
兩層校驗(yàn)保障文件完整:
一是客戶端上傳前計(jì)算視頻整體 MD5,與服務(wù)端預(yù)存的 MD5 比對,避免文件損壞后無效上傳。
二是分片合并時,OSS 會自動校驗(yàn)所有分片的 ETag 是否與客戶端上報的一致,只要有一個分片不匹配,就拒絕合并,防止最終視頻文件損壞。
這時,面試官又點(diǎn)了點(diǎn)頭,問到了系統(tǒng)中的高可用問題:“假設(shè)我們需要開發(fā)高并發(fā)、海量用戶的短視頻系統(tǒng),你會從哪些方面考慮呢?”
2. 轉(zhuǎn)碼服務(wù)的架構(gòu)設(shè)計(jì):兼顧效率與資源成本
轉(zhuǎn)碼是典型的 CPU 密集型操作,在高峰期,每秒可能有上萬條轉(zhuǎn)碼任務(wù)涌入,若架構(gòu)設(shè)計(jì)不合理,要么轉(zhuǎn)碼慢到用戶等不及,要么資源消耗過高導(dǎo)致成本飆升。
我們通過 “集群化 + 異步化” 的設(shè)計(jì),平衡效率與成本。
2.1 任務(wù)調(diào)度策略
采用 “優(yōu)先級隊(duì)列” 機(jī)制,根據(jù)用戶等級和視頻熱度分配資源。熱門用戶(粉絲數(shù) > 10 萬)的視頻轉(zhuǎn)碼任務(wù)設(shè)為 “高優(yōu)先級”,確保其內(nèi)容快速上線。
普通用戶任務(wù)設(shè)為 “中優(yōu)先級”;歸檔視頻(超過 3 個月無播放)設(shè)為 “低優(yōu)先級”,錯峰處理。
同時,轉(zhuǎn)碼服務(wù)通過 Kafka 分區(qū)實(shí)現(xiàn)任務(wù)分片,每個轉(zhuǎn)碼節(jié)點(diǎn)只消費(fèi)指定分區(qū)的任務(wù),避免重復(fù)處理和資源爭搶。
2.2 轉(zhuǎn)碼參數(shù)優(yōu)化
編碼格式和碼率是影響視頻質(zhì)量與存儲成本的關(guān)鍵。
我們選擇 H.265(HEVC)編碼,相比常用的 H.264,能節(jié)省 30% 的存儲空間,且支持移動端硬解碼,播放更流暢。碼率則分為三檔:480P(800kbps)適配 2G/3G 弱網(wǎng)環(huán)境,720P(1.5Mbps)應(yīng)對主流 WiFi,1080P(3Mbps)滿足 5G / 高速 WiFi 下的高清需求,客戶端會根據(jù)用戶當(dāng)前網(wǎng)速自動切換。
2.3 資源隔離
為避免不同業(yè)務(wù)爭搶資源,我們將轉(zhuǎn)碼集群按業(yè)務(wù)線拆分,直播轉(zhuǎn)碼和短視頻轉(zhuǎn)碼使用獨(dú)立集群 —— 比如直播高峰期(晚上 8-10 點(diǎn)),不會占用短視頻轉(zhuǎn)碼的 CPU 資源。
同時,通過 Linux cgroups 限制單個轉(zhuǎn)碼任務(wù)的最大 CPU 使用率(不超過 20%),防止單個大視頻轉(zhuǎn)碼拖垮整個節(jié)點(diǎn)。
3. 異常處理機(jī)制:保障流程穩(wěn)定性
在高并發(fā)場景下,異常是常態(tài),一套完善的異常處理機(jī)制,能讓系統(tǒng)在故障時 “不崩、不丟數(shù)據(jù)”:
- 上傳失敗重試:分片上傳超時(如 5 秒無響應(yīng))時,客戶端會自動重試 3 次,且每次重試間隔指數(shù)遞增(1 秒→2 秒→4 秒),減少網(wǎng)絡(luò)波動的影響。若 3 次重試仍失敗,上傳服務(wù)會將該視頻標(biāo)記為 “上傳異?!?,并觸發(fā)定時任務(wù)(每 10 分鐘)重新發(fā)起分片合并,避免用戶手動重試的麻煩。
- 轉(zhuǎn)碼失敗降級:若某一碼率轉(zhuǎn)碼失?。ū热?1080P 轉(zhuǎn)碼報錯),轉(zhuǎn)碼服務(wù)不會中斷整個任務(wù),而是跳過該碼率,優(yōu)先保證 480P 和 720P 可用,同時記錄失敗日志并觸發(fā)人工排查。對于轉(zhuǎn)碼超時的任務(wù)(如 30 分鐘未完成,通常是超大文件),會自動終止并降級為 “低優(yōu)先級”,待資源空閑時重新處理,不占用實(shí)時任務(wù)的資源。
- 數(shù)據(jù)一致性保障:上傳服務(wù)與轉(zhuǎn)碼服務(wù)通過 “視頻 ID” 唯一關(guān)聯(lián),轉(zhuǎn)碼完成后,必須更新 MySQL 中該視頻的 “轉(zhuǎn)碼狀態(tài)”。若超過 5 分鐘未更新,定時任務(wù)會重新發(fā)送轉(zhuǎn)碼任務(wù),防止數(shù)據(jù)丟失。此外,若 OSS 分片合并失敗,上傳服務(wù)會自動刪除已上傳的分片,避免存儲垃圾數(shù)據(jù),同時通知客戶端重新上傳。
講到這里,面試官已經(jīng)正襟危坐,透過電腦屏幕我看到他又開始打量起了我的簡歷,但這時我仿佛面試之神附身,意猶未盡,于是接著發(fā)揮。
三、性能優(yōu)化實(shí)踐
光穩(wěn)定還不夠,還要 “快”—— 用戶上傳快、視頻轉(zhuǎn)碼快、播放加載快,這需要針對性的性能優(yōu)化。
3.1 客戶端上傳速度優(yōu)化
- 并發(fā)分片上傳:客戶端同時發(fā)起 3-5 個分片上傳請求(根據(jù)網(wǎng)絡(luò)環(huán)境動態(tài)調(diào)整,弱網(wǎng)時降為 1-2 個),相比串行上傳,速度能提升 2-3 倍。比如一個 10MB 的視頻,拆分為 10 個 1MB 分片,并發(fā)上傳只需 2-3 秒,而串行上傳可能需要 5-6 秒。
- QUIC 協(xié)議替代 HTTP/2:在弱網(wǎng)環(huán)境(如地鐵、偏遠(yuǎn)地區(qū)),HTTP/2 的 TCP 連接容易丟包重傳,我們改用 QUIC 協(xié)議(基于 UDP),支持 0-RTT 連接建立,上傳成功率能提升 15% 以上(實(shí)測數(shù)據(jù))。比如在地鐵中,HTTP/2 上傳成功率約 70%,QUIC 能提升到 85% 以上。
- 預(yù)上傳校驗(yàn):客戶端上傳前先校驗(yàn)視頻格式(僅支持 MP4/AVI/MOV),不符合格式的直接提示用戶,避免無效上傳。同時提前計(jì)算分片 MD5,若發(fā)現(xiàn)分片損壞,直接丟棄并重新分片,減少上傳后校驗(yàn)失敗的概率。
3.2 轉(zhuǎn)碼效率優(yōu)化
- GPU 加速轉(zhuǎn)碼:對熱門視頻(日播放量 > 10 萬),我們采用 NVIDIA Tesla T4 GPU 進(jìn)行轉(zhuǎn)碼,相比傳統(tǒng) CPU(Intel Xeon 8375C),速度快 4-5 倍。比如一個 5 分鐘的視頻,CPU 轉(zhuǎn)碼需要 10 秒,GPU 轉(zhuǎn)碼只需 2 秒,大幅縮短視頻上線時間。
- 轉(zhuǎn)碼任務(wù)批量處理:當(dāng)同一創(chuàng)作者發(fā)布多個視頻時,我們會將這些視頻的轉(zhuǎn)碼任務(wù)合并,復(fù)用一次 OSS 連接和 FFmpeg 初始化資源,減少 IO 開銷。比如某創(chuàng)作者一次發(fā)布 3 個視頻,批量處理比單獨(dú)處理能節(jié)省 30% 的時間。
- 熱點(diǎn)視頻預(yù)轉(zhuǎn)碼:通過用戶行為預(yù)測提前觸發(fā)轉(zhuǎn)碼。比如某創(chuàng)作者歷史視頻播放量均破萬,當(dāng)其剛發(fā)布新視頻時,系統(tǒng)會預(yù)判該視頻會成為熱點(diǎn),提前啟動轉(zhuǎn)碼,避免用戶等待 —— 原本需要等轉(zhuǎn)碼完成才能觀看,現(xiàn)在發(fā)布后 1-2 秒就能加載播放。
講到這里,面試官趕緊示意我停止,說:“嗯 小伙子還不錯,短視頻這塊的上傳轉(zhuǎn)碼看來有專門了解過,好了,今天的面試先到這里吧,你有什么想問的嗎?”
于是我問了幾個不痛不癢的專業(yè)問題后,結(jié)束了這次面試。
小結(jié)
視頻上傳與轉(zhuǎn)碼作為短視頻系統(tǒng)的 “內(nèi)容入口”,是技術(shù)落地的關(guān)鍵一環(huán)。從分片上傳解決大文件傳輸問題,到轉(zhuǎn)碼服務(wù)平衡效率與成本,再到異常處理和性能優(yōu)化保障體驗(yàn),每一步都需要結(jié)合業(yè)務(wù)場景做精細(xì)化設(shè)計(jì)。
對于后臺開發(fā)者而言,理解這套流程不僅能應(yīng)對 “搭建短視頻系統(tǒng)” 的需求,更能將其中的技術(shù)思路(如分片傳輸、異步調(diào)度、資源隔離)遷移到其他大文件處理場景(如直播、云存儲)。
當(dāng)然,這只是短視頻系統(tǒng)的冰山一角,后續(xù)我們還會拆解視頻推薦、用戶互動等核心模塊。
































