|
導(dǎo)讀:直播彈幕是直播系統(tǒng)的核心功能之一。如何迅速作出一個(gè)有很好擴(kuò)展性的彈幕系統(tǒng)?如何應(yīng)對(duì)業(yè)務(wù)迅速發(fā)展?相信很多工程師/架構(gòu)師都有自己的想法。本文作者是美拍的架構(gòu)師,經(jīng)歷了直播彈幕從無(wú)到有,從小到大的過(guò)程。本文是作者對(duì)構(gòu)建彈幕系統(tǒng)的經(jīng)驗(yàn)總結(jié)。
直播彈幕指直播間的用戶(hù),禮物,評(píng)論,點(diǎn)贊等消息,是直播間交互的重要手段。美拍直播彈幕系統(tǒng)從 2015 年 11 月到現(xiàn)在,經(jīng)過(guò)了三個(gè)階段的演進(jìn),目前能支撐百萬(wàn)用戶(hù)同時(shí)在線(xiàn)。比較好地詮釋了根據(jù)項(xiàng)目的發(fā)展階段,進(jìn)行平衡演進(jìn)的過(guò)程。這三個(gè)階段分別是快速上線(xiàn),高可用保障體系建設(shè),長(zhǎng)連接演進(jìn)。 一、快速上線(xiàn) 消息模型 美拍直播彈幕系統(tǒng)在設(shè)計(jì)初期的核心要求是:快速上線(xiàn),并能支撐百萬(wàn)用戶(hù)同時(shí)在線(xiàn)。基于這兩點(diǎn),我們策略是前中期 HTTP 輪詢(xún)方案,中后期替換為長(zhǎng)連接方案。因此在業(yè)務(wù)團(tuán)隊(duì)進(jìn)行 HTTP 方案研發(fā)的同時(shí),基礎(chǔ)研發(fā)團(tuán)隊(duì)也緊鑼密鼓地開(kāi)發(fā)長(zhǎng)連接系統(tǒng)。 直播間消息,相對(duì)于 IM 的場(chǎng)景,有其幾個(gè)特點(diǎn)
對(duì)于用戶(hù)來(lái)說(shuō),在直播間有三個(gè)典型的操作:
我們把禮物,評(píng)論,用戶(hù)的數(shù)據(jù)都當(dāng)做消息來(lái)看待。經(jīng)過(guò)考慮選擇了 Redis 的 sortedset 存儲(chǔ)消息,消息模型如下:
因此總的流程是
不過(guò)這里有一個(gè)隱藏的并發(fā)問(wèn)題:用戶(hù)可能丟消息。 如上圖所示,某個(gè)用戶(hù)從第6號(hào)評(píng)論開(kāi)始拉取,同時(shí)有兩個(gè)用戶(hù)在發(fā)表評(píng)論,分別是10,11號(hào)評(píng)論。如果11號(hào)評(píng)論先寫(xiě)入,用戶(hù)剛好把6,7,8,9,11號(hào)拉走,用戶(hù)下次再拉取消息,就從12號(hào)開(kāi)始拉取,結(jié)果是:用戶(hù)沒(méi)有看到10號(hào)消息。 為了解決這個(gè)問(wèn)題,我們加上了兩個(gè)機(jī)制:
消息模型及并發(fā)問(wèn)題解決后,開(kāi)發(fā)就比較順暢,系統(tǒng)很快就上線(xiàn),達(dá)到預(yù)先預(yù)定目標(biāo)。 上線(xiàn)后暴露問(wèn)題的解決 上線(xiàn)后,隨著量的逐漸增加,系統(tǒng)陸續(xù)暴露出三個(gè)比較嚴(yán)重的問(wèn)題,我們一一進(jìn)行解決 問(wèn)題一:消息串行寫(xiě)入 Redis,如果某個(gè)直播間消息量很大,那么消息會(huì)堆積在 Kafka 中,消息延遲較大。 解決辦法:
問(wèn)題二:用戶(hù)輪詢(xún)最新消息,需要進(jìn)行 Redis 的 ZrangByScore 操作,redis slave 的性能瓶頸較大 解決辦法:
解釋?zhuān)哼@里本地緩存與平常使用的本地緩存問(wèn)題,有一個(gè)最大區(qū)別:成本問(wèn)題。 如果所有直播間的消息都進(jìn)行緩存,假設(shè)同時(shí)有1000個(gè)直播間,每個(gè)直播間5種消息類(lèi)型,本地緩存每隔1秒拉取一次數(shù)據(jù),40臺(tái)前端機(jī),那么對(duì) Redis 的訪(fǎng)問(wèn)QPS是 1000 * 5 * 40 = 20萬(wàn)。成本太高,因此我們只有大直播間才自動(dòng)開(kāi)啟本地緩存,小直播間不開(kāi)啟。 問(wèn)題三:彈幕數(shù)據(jù)也支持回放,直播結(jié)束后,這些數(shù)據(jù)存放于 Redis 中,在回放時(shí),會(huì)與直播的數(shù)據(jù)競(jìng)爭(zhēng) Redis 的 cpu 資源。 解決辦法:
解釋?zhuān)夯胤艜r(shí),讀取數(shù)據(jù)順序是: local cache -> Redis -> mysql。localcache 與回放 Redis 都可以只存某個(gè)直播某種消息類(lèi)型的部分?jǐn)?shù)據(jù),有效控制容量;local cache與回放 Redis 使用SortedSet數(shù)據(jù)結(jié)構(gòu),這樣整個(gè)系統(tǒng)的數(shù)據(jù)結(jié)構(gòu)都保持一致。 二、高可用保障 同城雙機(jī)房部署 分為主機(jī)房和從機(jī)房,寫(xiě)入都在主機(jī)房,讀取則由兩個(gè)機(jī)房分擔(dān)。從而有效保證單機(jī)房故障時(shí),能快速恢復(fù)。
全鏈路的業(yè)務(wù)監(jiān)控 高可用保障建設(shè)完成后,迎來(lái)了 TFBOYS 在美拍的四場(chǎng)直播,這四場(chǎng)直播峰值同時(shí)在線(xiàn)人數(shù)達(dá)到近百萬(wàn),共 2860萬(wàn)人次觀看,2980萬(wàn)評(píng)論,26.23億次點(diǎn)贊,直播期間,系統(tǒng)穩(wěn)定運(yùn)行,成功抗住壓力。 使用長(zhǎng)連接替換短連接輪詢(xún)方案 長(zhǎng)連接整體架構(gòu)圖如下 詳細(xì)說(shuō)明:
長(zhǎng)連接消息模型 我們采用了訂閱推送模型,下圖為基本的介紹 舉例說(shuō)明:用戶(hù)1訂閱了A直播,A直播有新的消息
如果是大直播間(訂閱用戶(hù)多),那么推送層與連接層的告知/拉取模型,就會(huì)自動(dòng)降級(jí)為廣播模型。如下圖所示 我們經(jīng)歷客戶(hù)端三個(gè)版本的迭代,實(shí)現(xiàn)了兩端(Android 與 iOS)長(zhǎng)連接對(duì)短連接的替換,因?yàn)橛谢叶群秃诎酌麊蔚闹С郑鎿Q非常平穩(wěn),用戶(hù)無(wú)感知。 總結(jié)與展望 回顧了系統(tǒng)的發(fā)展過(guò)程,達(dá)到了原定的前中期使用輪詢(xún),中后期使用長(zhǎng)連接的預(yù)定目標(biāo),實(shí)踐了原定的平衡演進(jìn)的原則。從發(fā)展來(lái)看,未來(lái)計(jì)劃要做的事情有
號(hào)外: 美圖架構(gòu),專(zhuān)注于虛擬化平臺(tái)建設(shè)、流媒體、云存儲(chǔ)、千萬(wàn)同時(shí)在線(xiàn)的通訊服務(wù)、音視頻編解碼等基礎(chǔ)設(shè)施建設(shè),現(xiàn)急需相關(guān)領(lǐng)域愛(ài)好者加入,工作地點(diǎn)可自由選擇北京、廈門(mén)、深圳,待遇從優(yōu),美女多多。現(xiàn)緊缺崗位如下:
|
|
|
來(lái)自: xujin3 > 《消息隊(duì)列》