乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      聊聊高并發(fā)長連接架構(gòu):百萬在線的美拍直播彈幕系統(tǒng)如何實現(xiàn)

       xujin3 2017-12-14

      導(dǎo)讀:直播彈幕是直播系統(tǒng)的核心功能之一。如何迅速作出一個有很好擴展性的彈幕系統(tǒng)?如何應(yīng)對業(yè)務(wù)迅速發(fā)展?相信很多工程師/架構(gòu)師都有自己的想法。本文作者是美拍的架構(gòu)師,經(jīng)歷了直播彈幕從無到有,從小到大的過程。本文是作者對構(gòu)建彈幕系統(tǒng)的經(jīng)驗總結(jié)。


      王靜波,畢業(yè)于西安交通大學(xué),曾任職于網(wǎng)易和新浪微博,微博工作期間負(fù)責(zé)開放平臺業(yè)務(wù)和技術(shù)體系建設(shè)。2015 年 9 月加入美圖,就職于架構(gòu)平臺部,目前負(fù)責(zé)部分核心業(yè)務(wù)和基礎(chǔ)設(shè)施的研發(fā)工作,包括彈幕服務(wù)、Feed 服務(wù)、任務(wù)調(diào)度和質(zhì)量監(jiān)控體系等。十余年的后端研發(fā)經(jīng)歷,擁有豐富的后端研發(fā)經(jīng)驗,對于構(gòu)建高可用、高并發(fā)的系統(tǒng)有較多實踐經(jīng)驗。歡迎通過 wjb@meitu.com 跟他交流。


      直播彈幕指直播間的用戶,禮物,評論,點贊等消息,是直播間交互的重要手段。美拍直播彈幕系統(tǒng)從 2015 年 11 月到現(xiàn)在,經(jīng)過了三個階段的演進,目前能支撐百萬用戶同時在線。比較好地詮釋了根據(jù)項目的發(fā)展階段,進行平衡演進的過程。這三個階段分別是快速上線,高可用保障體系建設(shè),長連接演進。


      一、快速上線


      消息模型


      美拍直播彈幕系統(tǒng)在設(shè)計初期的核心要求是:快速上線,并能支撐百萬用戶同時在線。基于這兩點,我們策略是前中期 HTTP 輪詢方案,中后期替換為長連接方案。因此在業(yè)務(wù)團隊進行 HTTP 方案研發(fā)的同時,基礎(chǔ)研發(fā)團隊也緊鑼密鼓地開發(fā)長連接系統(tǒng)。


      直播間消息,相對于 IM 的場景,有其幾個特點


      • 消息要求及時,過時的消息對于用戶來說不重要;

      • 松散的群聊,用戶隨時進群,隨時退群;

      • 用戶進群后,離線期間(接聽電話)的消息不需要重發(fā);


      對于用戶來說,在直播間有三個典型的操作:


      • 進入直播間,拉取正在觀看直播的用戶列表

      • 接收直播間持續(xù)接收彈幕消息;

      • 自己發(fā)消息


      我們把禮物,評論,用戶的數(shù)據(jù)都當(dāng)做消息來看待。經(jīng)過考慮選擇了 Redis 的 sortedset 存儲消息,消息模型如下:


      • 用戶發(fā)消息,通過 Zadd,其中 score 消息的相對時間;

      • 接收直播間的消息,通過 ZrangeByScore 操作,兩秒一次輪詢;

      • 進入直播間,獲取用戶的列表,通過 Zrange 操作來完成;

       

      因此總的流程是


      • 寫消息流程是:  前端機 -> Kafka -> 處理機 -> Redis

      • 讀消息流程是:  前端 -> Redis


      不過這里有一個隱藏的并發(fā)問題:用戶可能丟消息。



      如上圖所示,某個用戶從第6號評論開始拉取,同時有兩個用戶在發(fā)表評論,分別是10,11號評論。如果11號評論先寫入,用戶剛好把6,7,8,9,11號拉走,用戶下次再拉取消息,就從12號開始拉取,結(jié)果是:用戶沒有看到10號消息。


      為了解決這個問題,我們加上了兩個機制:


      • 在前端機,同一個直播間的同一種消息類型,寫入 Kafka 的同一個 partition

      • 在處理機,同一個直播間的同一種消息類型,通過 synchronized 保證寫入 Redis 的串行。


      消息模型及并發(fā)問題解決后,開發(fā)就比較順暢,系統(tǒng)很快就上線,達到預(yù)先預(yù)定目標(biāo)。


      上線后暴露問題的解決


      上線后,隨著量的逐漸增加,系統(tǒng)陸續(xù)暴露出三個比較嚴(yán)重的問題,我們一一進行解決


      問題一:消息串行寫入 Redis,如果某個直播間消息量很大,那么消息會堆積在 Kafka 中,消息延遲較大。


      解決辦法:


      • 消息寫入流程:前端機-> Kafka -> 處理機 -> Redis

      • 前端機:如果延遲小,則只寫入一個 Kafka 的partion;如果延遲大,則這個直播的這種消息類型寫入 Kafka 的多個partion。

      • 處理機:如果延遲小,加鎖串行寫入 Redis;如果延遲大,則取消鎖。因此有四種組合,四個檔位,分別是

        • 一個partion, 加鎖串行寫入 Redis, 最大并發(fā)度:1

        • 多個partition,加鎖串行寫入 Redis, 最大并發(fā)度:Kafka partion的個數(shù)

        • 一個partion, 不加鎖并行寫入 Redis, 最大并發(fā)度: 處理機的線程池個數(shù)

        • 多個partion, 不加鎖并行寫入 Redis,最大并發(fā)度: Kafka partition個數(shù)處理機線程池的個數(shù)

      • 延遲程度判斷:前端機寫入消息時,打上消息的統(tǒng)一時間戳,處理機拿到后,延遲時間 = 現(xiàn)在時間 - 時間戳;

      • 檔位選擇:自動選擇檔位,粒度:某個直播間的某個消息類型


      問題二:用戶輪詢最新消息,需要進行 Redis 的 ZrangByScore 操作,redis slave 的性能瓶頸較大


      解決辦法:


      • 本地緩存,前端機每隔1秒左右取拉取一次直播間的消息,用戶到前端機輪詢數(shù)據(jù)時,從本地緩存讀取數(shù)據(jù);

      • 消息的返回條數(shù)根據(jù)直播間的大小自動調(diào)整,小直播間返回允許時間跨度大一些的消息,大直播間則對時間跨度以及消息條數(shù)做更嚴(yán)格的限制。

       

      解釋:這里本地緩存與平常使用的本地緩存問題,有一個最大區(qū)別:成本問題。


      如果所有直播間的消息都進行緩存,假設(shè)同時有1000個直播間,每個直播間5種消息類型,本地緩存每隔1秒拉取一次數(shù)據(jù),40臺前端機,那么對 Redis 的訪問QPS是   1000 * 5 * 40 = 20萬。成本太高,因此我們只有大直播間才自動開啟本地緩存,小直播間不開啟。


      問題三:彈幕數(shù)據(jù)也支持回放,直播結(jié)束后,這些數(shù)據(jù)存放于 Redis 中,在回放時,會與直播的數(shù)據(jù)競爭 Redis 的 cpu 資源。


      解決辦法:


      • 直播結(jié)束后,數(shù)據(jù)備份到 mysql;

      • 增加一組回放的 Redis;

      • 前端機增加回放的 local cache;

       

      解釋:回放時,讀取數(shù)據(jù)順序是: local cache -> Redis -> mysql。localcache 與回放 Redis 都可以只存某個直播某種消息類型的部分?jǐn)?shù)據(jù),有效控制容量;local cache與回放 Redis 使用SortedSet數(shù)據(jù)結(jié)構(gòu),這樣整個系統(tǒng)的數(shù)據(jù)結(jié)構(gòu)都保持一致。


      二、高可用保障


      同城雙機房部署


      分為主機房和從機房,寫入都在主機房,讀取則由兩個機房分擔(dān)。從而有效保證單機房故障時,能快速恢復(fù)。


      豐富的降級手段



      全鏈路的業(yè)務(wù)監(jiān)控



      高可用保障建設(shè)完成后,迎來了 TFBOYS 在美拍的四場直播,這四場直播峰值同時在線人數(shù)達到近百萬,共 2860萬人次觀看,2980萬評論,26.23億次點贊,直播期間,系統(tǒng)穩(wěn)定運行,成功抗住壓力。


      使用長連接替換短連接輪詢方案


      長連接整體架構(gòu)圖如下



      詳細(xì)說明:


      • 客戶端在使用長連接前,會調(diào)用路由服務(wù),獲取連接層IP,路由層特性:a. 可以按照百分比灰度;b. 可以對 uid,deviceId,版本進行黑白名單設(shè)置。黑名單:不允許使用長連接;白名單:即使長連接關(guān)閉或者不在灰度范圍內(nèi),也允許使用長連接。這兩個特性保證了我們長短連接切換的順利進行;

      • 客戶端的特性:a. 同時支持長連接和短連接,可根據(jù)路由服務(wù)的配置來決定;b. 自動降級,如果長連接同時三次連接不上,自動降級為短連接;c. 自動上報長連接性能數(shù)據(jù);

      • 連接層只負(fù)責(zé)與客戶端保持長連接,沒有任何推送的業(yè)務(wù)邏輯。從而大大減少重啟的次數(shù),從而保持用戶連接的穩(wěn)定;

      • 推送層存儲用戶與直播間的訂閱關(guān)系,負(fù)責(zé)具體推送。整個連接層與推送層與直播間業(yè)務(wù)無關(guān),不需要感知到業(yè)務(wù)的變化;

      • 長連接業(yè)務(wù)模塊用于用戶進入直播間的驗證工作;

      • 服務(wù)端之間的通訊使用基礎(chǔ)研發(fā)團隊研發(fā)的tardis框架來進行服務(wù)的調(diào)用,該框架基于 gRPC,使用 etcd 做服務(wù)發(fā)現(xiàn);


      長連接消息模型


      我們采用了訂閱推送模型,下圖為基本的介紹



      舉例說明:用戶1訂閱了A直播,A直播有新的消息


      • 推送層查詢訂閱關(guān)系后,知道有用戶1訂閱了A直播,同時知道用戶1在連接層1這個節(jié)點上,那么就會告知連接層有新的消息

      • 連接層1收到告知消息后,會等待一小段時間(毫秒級),再拉取一次用戶1的消息,然后推送給用戶1.


      如果是大直播間(訂閱用戶多),那么推送層與連接層的告知/拉取模型,就會自動降級為廣播模型。如下圖所示



      我們經(jīng)歷客戶端三個版本的迭代,實現(xiàn)了兩端(Android 與 iOS)長連接對短連接的替換,因為有灰度和黑白名單的支持,替換非常平穩(wěn),用戶無感知。


      總結(jié)與展望


      回顧了系統(tǒng)的發(fā)展過程,達到了原定的前中期使用輪詢,中后期使用長連接的預(yù)定目標(biāo),實踐了原定的平衡演進的原則。從發(fā)展來看,未來計劃要做的事情有


      • 針對機房在北京,南方某些地區(qū)會存在連接時間長的情況。我們?nèi)绾巫岄L連接更靠近用戶。

      • 消息模型的進一步演進。


      號外:


      美圖架構(gòu),專注于虛擬化平臺建設(shè)、流媒體、云存儲、千萬同時在線的通訊服務(wù)、音視頻編解碼等基礎(chǔ)設(shè)施建設(shè),現(xiàn)急需相關(guān)領(lǐng)域愛好者加入,工作地點可自由選擇北京、廈門、深圳,待遇從優(yōu),美女多多?,F(xiàn)緊缺崗位如下:


      • Go/C 開發(fā)工程師:我們 50% 以上代碼使用 Go

      • Java 開發(fā)工程師

      • 音視頻編解碼研究人員

      • Docker 虛擬化底層研發(fā)工程師 

        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多