聽說你會(huì)架構(gòu)設(shè)計(jì),來,弄一個(gè)短視頻系統(tǒng)
引言
不知道各位后臺(tái)開發(fā)者有沒有過這樣的經(jīng)歷:在地鐵上刷著抖音停不下來,回家后又在快手上看各類生活分享。
可當(dāng)產(chǎn)品經(jīng)理拍著你的肩膀說 “咱們也搞個(gè)短視頻系統(tǒng)” 時(shí),瞬間從 “用戶” 切換到 “開發(fā)者” 視角,滿腦子都是 海量視頻存儲(chǔ)怎么搞、高并發(fā)推流怎么扛、實(shí)時(shí)推薦怎么做到精準(zhǔn) 的靈魂拷問。
在當(dāng)下的互聯(lián)網(wǎng)生態(tài)中,短視頻早已成為用戶時(shí)長占比最高的應(yīng)用形態(tài)之一。
某音、某手等頭部平臺(tái)單日活躍用戶數(shù)以億計(jì),每秒都有上萬條視頻被 上傳、轉(zhuǎn)碼、分發(fā),同時(shí)還有億級(jí)用戶在實(shí)時(shí) 刷新、觀看、互動(dòng)。
要支撐這樣龐大的業(yè)務(wù)規(guī)模,背后的系統(tǒng)架構(gòu)設(shè)計(jì)絕非簡單的 “CRUD + 文件存儲(chǔ)” 就能搞定。
本文將以某音、某手為參考原型,從后臺(tái)技術(shù)視角拆解短視頻系統(tǒng)的架構(gòu)設(shè)計(jì),涵蓋整體架構(gòu)分層、核心功能技術(shù)實(shí)現(xiàn)、關(guān)鍵技術(shù)難點(diǎn)突破等內(nèi)容,為各位開發(fā)者提供一套可落地的短視頻系統(tǒng)架構(gòu)思路,讓你面對(duì) “搞個(gè)短視頻系統(tǒng)” 的需求時(shí),能從容給出技術(shù)方案。
一、整體架構(gòu)
短視頻系統(tǒng)是典型的 “高并發(fā)、海量數(shù)據(jù)、低延遲” 綜合系統(tǒng),需兼顧 視頻生產(chǎn)(上傳、轉(zhuǎn)碼)、內(nèi)容分發(fā)(推薦、CDN)、用戶互動(dòng)(點(diǎn)贊、評(píng)論、分享) 三大核心鏈路,整體采用 “分層解耦 + 微服務(wù)化” 架構(gòu)設(shè)計(jì),從下到上可分為基礎(chǔ)組件層、核心服務(wù)層、算法引擎層、接入層四層,同時(shí)配套監(jiān)控運(yùn)維體系保障系統(tǒng)穩(wěn)定性。
1.1 架構(gòu)圖
圖片
1.2 關(guān)鍵組件說明
(1)接入層
- API 網(wǎng)關(guān):采用 Kong/APISIX,負(fù)責(zé)請(qǐng)求路由、鑒權(quán)(JWT/OAuth2.0)、限流(令牌桶算法)、灰度發(fā)布(基于 用戶 ID / 地域 的流量切分),同時(shí)統(tǒng)一處理跨域、請(qǐng)求參數(shù)校驗(yàn),屏蔽后端服務(wù)復(fù)雜性。
- 負(fù)載均衡:使用 Nginx/LVS,結(jié)合 DNS 輪詢實(shí)現(xiàn) 地域級(jí)流量分發(fā),將用戶請(qǐng)求引導(dǎo)至就近的機(jī)房節(jié)點(diǎn),降低網(wǎng)絡(luò)延遲(如北京用戶接入北京機(jī)房,廣州用戶接入廣州機(jī)房)。
- 灰度發(fā)布:在關(guān)鍵功能上線時(shí),特別是一些商業(yè)化能力,需要通過用戶反饋、數(shù)據(jù)看板來查看當(dāng)前功能的實(shí)踐性,所以在發(fā)布時(shí),我們會(huì)在網(wǎng)關(guān)層配置 用戶灰度 比例(如采用 Hash 桶散列分布的方式),讓一部分用戶首先體驗(yàn)到新功能。
(2)核心服務(wù)層
- 視頻生產(chǎn)服務(wù):負(fù)責(zé)視頻 上傳、轉(zhuǎn)碼、審核 流程,拆分為上傳服務(wù)(接收客戶端視頻分片)、轉(zhuǎn)碼服務(wù)(調(diào)用轉(zhuǎn)碼集群處理多碼率)、審核服務(wù)(對(duì)接內(nèi)容審核接口)三個(gè)微服務(wù)。
- 視頻分發(fā)服務(wù):核心是 “推流 - 拉流” 鏈路,包含 推流 服務(wù)(接收轉(zhuǎn)碼后的視頻流,寫入 CDN 源站)、拉流 服務(wù)(為客戶端提供視頻播放地址,支持?jǐn)帱c(diǎn)續(xù)傳)、緩存 服務(wù)(Redis 緩存熱門視頻元數(shù)據(jù),減少 DB 訪問)。
- 互動(dòng)服務(wù):處理點(diǎn)贊、評(píng)論、分享、關(guān)注等互動(dòng)行為,拆分為互動(dòng)服務(wù)(處理點(diǎn)贊 / 評(píng)論的增刪改查)、關(guān)系服務(wù)(管理用戶關(guān)注 / 粉絲關(guān)系)、消息服務(wù)(推送評(píng)論通知 / 關(guān)注通知),本文主要關(guān)注核心模塊的互動(dòng)服務(wù)。
- 用戶服務(wù):管理用戶基礎(chǔ)信息(賬號(hào)、昵稱、頭像)、登錄態(tài)(Session/Token 管理)、權(quán)益(會(huì)員特權(quán)、創(chuàng)作激勵(lì)),數(shù)據(jù)存儲(chǔ)采用 MySQL 分庫分表(按用戶 ID 哈希分片)。
(3)算法引擎層
- 推薦模塊:核心是 “實(shí)時(shí)推薦 + 離線推薦” 雙引擎,離線推薦基于 Spark/Flink 計(jì)算用戶長期興趣(T+1 更新),實(shí)時(shí)推薦基于 Flink 流處理計(jì)算用戶短期興趣(秒級(jí)更新),最終通過推薦 API 返回個(gè)性化視頻列表。
- 用戶畫像模塊:基于用戶基礎(chǔ)信息、互動(dòng)行為(點(diǎn)贊 / 評(píng)論 / 完播率)、觀看時(shí)長等數(shù)據(jù),通過 ES(Elasticsearch)存儲(chǔ)用戶標(biāo)簽(如 “喜歡美食”“關(guān)注汽車”),為推薦、內(nèi)容審核提供數(shù)據(jù)支撐。
- 內(nèi)容審核模塊:結(jié)合 AI 審核(識(shí)別違規(guī)畫面 / 文字)和人工審核,對(duì)上傳的視頻進(jìn)行實(shí)時(shí)過濾,違規(guī)視頻直接攔截,疑似違規(guī)視頻進(jìn)入人工審核隊(duì)列,保障內(nèi)容合規(guī)性。
(4)基礎(chǔ)組件層
- 存儲(chǔ)組件:視頻文件存儲(chǔ)采用 對(duì)象存儲(chǔ)(S3/OSS),支持海量文件存儲(chǔ)和高并發(fā)訪問;結(jié)構(gòu)化數(shù)據(jù) (用戶信息、互動(dòng)記錄)存儲(chǔ)采用 MySQL(主從架構(gòu)),非結(jié)構(gòu)化數(shù)據(jù) (用戶畫像、日志)存儲(chǔ)采用 ES/HDFS;緩存 采用 Redis(集群模式,分片 + 哨兵),緩存熱門視頻元數(shù)據(jù)和用戶登錄態(tài)。
- 計(jì)算組件:離線計(jì)算 采用 Spark(處理用戶畫像、推薦模型訓(xùn)練),實(shí)時(shí)計(jì)算 采用 Flink(處理實(shí)時(shí)推薦、用戶行為日志),為算法引擎提供算力支撐。
- 消息隊(duì)列:采用 Kafka(集群模式),解耦 服務(wù)間依賴,如視頻上傳完成后發(fā)送 “轉(zhuǎn)碼任務(wù)” 消息,轉(zhuǎn)碼完成后發(fā)送 “審核任務(wù)” 消息,避免服務(wù)直接調(diào)用導(dǎo)致的耦合。
- CDN:對(duì)接阿里云 / 騰訊云 CDN,將轉(zhuǎn)碼后的視頻緩存到全國節(jié)點(diǎn),用戶拉取視頻時(shí)從就近 CDN 節(jié)點(diǎn)獲取,降低源站壓力,提升播放速度。
二、核心功能技術(shù)實(shí)現(xiàn)
圖片
2.1 視頻上傳與轉(zhuǎn)碼
- 上傳流程:客戶端采用 “分片上傳”(將視頻分成 1MB / 片),通過 HTTP/2 協(xié)議上傳至上傳服務(wù),上傳服務(wù)校驗(yàn)分片完整性后,調(diào)用對(duì)象存儲(chǔ)合并分片,生成視頻源文件;同時(shí)發(fā)送 “轉(zhuǎn)碼任務(wù)” 到 Kafka,轉(zhuǎn)碼服務(wù)消費(fèi)消息后,調(diào)用 FFmpeg 轉(zhuǎn)碼集群,將源視頻轉(zhuǎn)成 480P/720P/1080P 多碼率格式,轉(zhuǎn)碼完成后更新視頻元數(shù)據(jù)狀態(tài)。
- 關(guān)鍵技術(shù):分片上傳(斷點(diǎn)續(xù)傳,避免網(wǎng)絡(luò)中斷重傳整個(gè)視頻)、異步轉(zhuǎn)碼(采用 Celery 任務(wù)隊(duì)列,支持任務(wù)優(yōu)先級(jí),熱門用戶視頻優(yōu)先轉(zhuǎn)碼)、QUIC 協(xié)議(弱網(wǎng)環(huán)境下提升上傳速度,降低丟包率)。
想要詳細(xì)了解視頻上傳和轉(zhuǎn)碼的可以看我之前的文章:短視頻上傳與轉(zhuǎn)碼全流程解析
2.2 視頻推薦與分發(fā)
- 推薦流程:用戶打開 APP 后,客戶端調(diào)用推薦 API,推薦服務(wù)先從 Redis 獲取 “用戶短期興趣標(biāo)簽”(如最近 1 小時(shí)點(diǎn)贊的視頻類型),再從 Spark 離線計(jì)算結(jié)果中獲取 “用戶長期興趣標(biāo)簽”,結(jié)合用戶地域、設(shè)備型號(hào)等信息,從 ES 中篩選符合條件的視頻列表,通過負(fù)載均衡返回給客戶端;同時(shí),用戶觀看視頻的行為(完播 / 點(diǎn)贊 / 評(píng)論)實(shí)時(shí)上報(bào)至 Flink 集群,更新用戶實(shí)時(shí)興趣標(biāo)簽,用于下一次推薦。
- 關(guān)鍵技術(shù):協(xié)同過濾算法(基于用戶行為相似性推薦)、深度學(xué)習(xí)模型(如 DeepFM,融合用戶特征和視頻特征)、緩存預(yù)熱(將熱門推薦列表提前緩存到 Redis,降低推薦服務(wù)響應(yīng)時(shí)間)。
想要詳細(xì)了解推薦與分發(fā)的可以看我之前的文章:5張圖帶你深入短視頻推薦分發(fā)背后的技術(shù)邏輯
2.3 用戶互動(dòng)(點(diǎn)贊 / 評(píng)論)
圖片
- 點(diǎn)贊流程:客戶端發(fā)送點(diǎn)贊請(qǐng)求到互動(dòng)服務(wù),互動(dòng)服務(wù)先校驗(yàn)用戶登錄態(tài),再判斷用戶是否已點(diǎn)贊(Redis 查詢,避免重復(fù)點(diǎn)贊),未點(diǎn)贊則更新 MySQL(點(diǎn)贊表,按用戶 ID 分表)和 Redis(用戶點(diǎn)贊集合),同時(shí)發(fā)送 “點(diǎn)贊通知” 消息到 Kafka,消息服務(wù)消費(fèi)后推送通知給視頻作者。
- 關(guān)鍵技術(shù):Redis 分布式鎖(避免并發(fā)點(diǎn)贊導(dǎo)致的數(shù)據(jù)不一致)、MySQL 分表(按用戶 ID 哈希分表,支撐億級(jí)用戶互動(dòng)數(shù)據(jù)存儲(chǔ))、讀寫分離(點(diǎn)贊查詢走 Redis,寫入走 MySQL 主庫,讀走從庫)、CDN 預(yù)熱提升互動(dòng)拉取的速度。
三、技術(shù)難點(diǎn)與解決方案
3.1 海量視頻存儲(chǔ)成本控制
問題拆解
短視頻單文件 10-50MB,億級(jí)存量視頻需至少 100PB 存儲(chǔ)空間(按 1 億條、平均 10MB 計(jì)算),若全用標(biāo)準(zhǔn)存儲(chǔ),年成本超千萬元。
且視頻訪問存在 “冷熱分化”—— 近 30 天視頻播放量占總播放量的 80%,老舊視頻訪問頻次極低,全量高成本存儲(chǔ)造成資源浪費(fèi)。
分層存儲(chǔ)策略
圖片
首先,我們定義 “熱 / 溫 / 冷” 三級(jí)數(shù)據(jù):
- 熱門視頻(近 7 天播放量 Top10%、或單日播放量 > 1000 次)存對(duì)象存儲(chǔ) SSD 節(jié)點(diǎn)(如阿里云 OSS 高性能版),保障毫秒級(jí)拉流響應(yīng);
- 普通視頻(近 30 天有播放、非熱門)存 HDD 標(biāo)準(zhǔn)節(jié)點(diǎn)(成本為 SSD 的 1/2);
- 歸檔視頻(超過 3 個(gè)月無播放、或用戶主動(dòng)歸檔)遷移至冷存儲(chǔ)(如 OSS 歸檔版,成本僅為標(biāo)準(zhǔn)存儲(chǔ)的 1/5)。
具體實(shí)現(xiàn)
通過定時(shí)任務(wù)(如 Crontab 離線作業(yè),每日凌晨執(zhí)行)統(tǒng)計(jì)視頻播放量,觸發(fā)存儲(chǔ)級(jí)別自動(dòng)遷移。
同時(shí)提供 “手動(dòng)歸檔” API,允許創(chuàng)作者將歷史視頻轉(zhuǎn)入冷存儲(chǔ),遷移過程中通過 “軟鏈接” 保持播放地址不變,避免用戶感知。
視頻壓縮優(yōu)化
轉(zhuǎn)碼階段默認(rèn)采用 H.265 編碼(對(duì)比 H.264,相同清晰度下碼率降低 30%,即 10MB 視頻可壓縮至 7MB),同時(shí)針對(duì)不同場景做適配:短視頻(15-60 秒)碼率控制在 500-1500kbps(480P→500kbps、720P→1000kbps、1080P→1500kbps),避免碼率冗余;長視頻(超過 1 分鐘)采用 “動(dòng)態(tài)碼率”(VBR),畫面復(fù)雜段提高碼率、靜態(tài)段降低碼率,進(jìn)一步節(jié)省 20% 存儲(chǔ)。
兼容性處理
針對(duì)不支持 H.265 的老舊設(shè)備(如部分 Android 7.0 以下機(jī)型),轉(zhuǎn)碼時(shí)額外生成 H.264 低碼率版本,客戶端通過設(shè)備檢測接口選擇對(duì)應(yīng)格式,兼顧兼容性與成本。
3.2 高并發(fā)推流與低延遲播放
問題拆解
峰值時(shí)段(如晚間 8-10 點(diǎn))每秒新增 1000 + 條推流請(qǐng)求,若直接推至源站,會(huì)導(dǎo)致源站帶寬瓶頸。
同時(shí)百萬級(jí)用戶同時(shí)拉流時(shí),單節(jié)點(diǎn)帶寬壓力超 10Gbps,易出現(xiàn)丟包、延遲(>3 秒),播放卡頓率超 5% 會(huì)顯著降低用戶留存。
推流側(cè):邊緣節(jié)點(diǎn)
圖片
架構(gòu)設(shè)計(jì)
客戶端通過 DNS 解析獲取就近邊緣節(jié)點(diǎn)(如用戶在杭州,解析到阿里云杭州邊緣節(jié)點(diǎn)),視頻分片先上傳至邊緣節(jié)點(diǎn),邊緣節(jié)點(diǎn)完成 “分片校驗(yàn) + 臨時(shí)存儲(chǔ)” 后,再異步同步至中心源站(采用增量同步,僅傳輸新分片),避免源站直接承接高并發(fā)推流。
技術(shù)實(shí)現(xiàn)
邊緣節(jié)點(diǎn)部署 “推流代理服務(wù)”(基于 Nginx-RTMP 模塊二次開發(fā)),支持 HTTP/2 和 QUIC 協(xié)議;客戶端分片上傳時(shí),邊緣節(jié)點(diǎn)返回 “分片唯一標(biāo)識(shí)”,若網(wǎng)絡(luò)中斷,客戶端可通過標(biāo)識(shí)續(xù)傳未完成分片,重傳成功率提升至 99%。
拉流側(cè):CDN 多級(jí)緩存 + 播放優(yōu)化
CDN 緩存策略
采用 “邊緣節(jié)點(diǎn)→區(qū)域節(jié)點(diǎn)→源站” 三級(jí)緩存,熱門視頻(播放量 > 10 萬次)直接緩存至邊緣節(jié)點(diǎn)(覆蓋全國 300 + 城市),用戶拉流時(shí)延遲 < 100ms;普通視頻 緩存至區(qū)域節(jié)點(diǎn)(如華東、華南區(qū)域中心),邊緣節(jié)點(diǎn)無緩存時(shí)從區(qū)域節(jié)點(diǎn)拉取,避免直接訪問源站。
客戶端優(yōu)化
實(shí)現(xiàn) “預(yù)加載 + 自適應(yīng)碼率” 雙機(jī)制 —— 用戶播放當(dāng)前視頻時(shí),后臺(tái)預(yù)加載下一個(gè)推薦視頻(預(yù)加載 50% 內(nèi)容),切換視頻時(shí)實(shí)現(xiàn) “無縫播放”;同時(shí)客戶端實(shí)時(shí)檢測網(wǎng)速(每 2 秒計(jì)算一次下載速率),若網(wǎng)速 < 1Mbps 自動(dòng)切換至 480P,1-3Mbps 切換至 720P,>3Mbps 切換至 1080P,卡頓率可控制在 1% 以內(nèi)。
3.3 實(shí)時(shí)推薦系統(tǒng)高可用
問題拆解
實(shí)時(shí)推薦依賴三大環(huán)節(jié) ——Flink 實(shí)時(shí)計(jì)算(秒級(jí)更新用戶短期興趣)、ES 檢索(毫秒級(jí)篩選視頻)、推薦服務(wù) API(聚合結(jié)果),任一環(huán)節(jié)故障(如 Flink 集群重啟、ES 分片異常)都會(huì)導(dǎo)致推薦列表空白或返回錯(cuò)誤內(nèi)容,影響核心用戶體驗(yàn)(推薦列表是短視頻 APP 的主要流量入口,不可用會(huì)導(dǎo)致 DAU 下降 40%+)。
多級(jí)降級(jí)預(yù)案
圖片
一級(jí)降級(jí)(實(shí)時(shí)引擎故障)
當(dāng) Flink 實(shí)時(shí)計(jì)算集群延遲 > 5 秒(通過監(jiān)控告警檢測),推薦服務(wù)自動(dòng)切換至 “離線推薦 + 短期緩存” 模式 —— 使用 Spark T+1 離線計(jì)算的用戶長期興趣標(biāo)簽,結(jié)合 Redis 緩存的 “用戶最近 1 小時(shí)互動(dòng)視頻類型”(如最近點(diǎn)贊過 “美食”),生成推薦列表,避免實(shí)時(shí)數(shù)據(jù)缺失導(dǎo)致的興趣偏差。
二級(jí)降級(jí)(ES 故障)
當(dāng) ES 集群健康度 <90%(如分片不可用),推薦服務(wù)直接返回 Redis 中緩存的 “熱門視頻列表”(每 10 分鐘更新一次,存儲(chǔ) Top1000 條熱門視頻),同時(shí)標(biāo)記 “降級(jí)狀態(tài)”,前端顯示 “熱門推薦” 標(biāo)識(shí),降低用戶感知。
三級(jí)降級(jí)(推薦服務(wù)過載)
通過 Sentinel 配置推薦 API 的 QPS 閾值(如單節(jié)點(diǎn) 1000QPS),當(dāng)并發(fā)超閾值時(shí),自動(dòng)返回 “簡化推薦列表”(僅返回 20 條視頻,而非默認(rèn) 50 條),同時(shí)拒絕非核心推薦請(qǐng)求(如 “相似視頻推薦”),優(yōu)先保障首頁主推薦流可用。
數(shù)據(jù)一致性保障
離線推薦結(jié)果預(yù)加載
每日凌晨 Spark 離線計(jì)算完成后,將用戶長期興趣推薦列表提前寫入 Redis(按用戶 ID 分片存儲(chǔ)),推薦服務(wù)優(yōu)先從 Redis 讀取,減少 ES 訪問依賴;同時(shí)通過 “版本號(hào)機(jī)制” 確保 Redis 與 ES 數(shù)據(jù)同步 —— 當(dāng) ES 數(shù)據(jù)更新時(shí),同步更新 Redis 中的版本號(hào),推薦服務(wù)發(fā)現(xiàn)版本不一致時(shí)觸發(fā)增量更新。
故障恢復(fù)自動(dòng)切換
通過監(jiān)控系統(tǒng)(如 Prometheus+Grafana)實(shí)時(shí)檢測各環(huán)節(jié)狀態(tài),當(dāng)故障環(huán)節(jié)恢復(fù)(如 Flink 延遲恢復(fù)正常、ES 分片重新分配完成),推薦服務(wù)自動(dòng)切換回正常模式,切換過程無感知(通過雙活服務(wù)部署,舊模式服務(wù)繼續(xù)處理存量請(qǐng)求,新模式服務(wù)承接增量請(qǐng)求,待存量請(qǐng)求處理完后下線舊模式)。
四、小結(jié):從 “滿頭問號(hào)” 到 “架構(gòu)落地”,我們還能走得更遠(yuǎn)
寫這篇架構(gòu)拆解時(shí),我總會(huì)想起第一次接 “做短視頻系統(tǒng)” 需求的場景 —— 對(duì)著產(chǎn)品經(jīng)理畫的 “某音同款” 原型圖,手里的筆懸了半小時(shí),滿腦子都是 “這億級(jí)視頻存哪里”“百萬并發(fā)怎么抗” 的焦慮。
但當(dāng)把架構(gòu)拆成 “接入層擋請(qǐng)求、核心服務(wù)做流轉(zhuǎn)、算法引擎給智能、基礎(chǔ)組件托底” 四層后,突然發(fā)現(xiàn)復(fù)雜問題也能 “化整為零”。
回頭看全文,我們其實(shí)只做了三件事:把模糊需求拆成技術(shù)模塊(比如把 “視頻上線” 拆成上傳、轉(zhuǎn)碼、審核三步),給每個(gè)模塊選對(duì)工具(推流用邊緣節(jié)點(diǎn)卸壓、推薦用 Spark+Flink 雙引擎),給關(guān)鍵痛點(diǎn)留好退路(存儲(chǔ)分冷熱控成本、推薦做三級(jí)降級(jí)??捎茫?。
這些方案沒有什么 “黑科技”,但勝在落地性 —— 畢竟對(duì)開發(fā)者來說,能 扛住流量、控住成本、不出故障的架構(gòu),才是好架構(gòu)。




































