原文:Globo.com’s Live Video Platform for FIFA World Cup ’14- Part II – DVR and Microservices
作者: Floyd Smith ? ? ? 譯者:杰微刊兼職翻譯汪建?
下文改編自環(huán)球網的Leandro Moreira 和Juarez Bochi兩位工程師 2015年九月份在San Francisco市舉辦的nginx會議的演講钦无。這篇博客是兩部分的第二部分,這部分主要關注與使用nginx構建微服務辐棒。第一部分主要講了傳輸及緩存方面的工作航徙,可以在https://www.nginx.com/blog/globo-coms-live-video-platform-fifa-world-cup-14-part-delivery-caching/這里找到,同樣你也可以從YouTube上觀看完整的研究視頻厂置。
內容表
19:02 DVR
20:24 DVR的挑戰(zhàn)——故障轉移
21:06 DVR的挑戰(zhàn)——存儲
22:11 使用Redis作為數據存儲
23:20 巴西大選
24:12 從Redis到Cassandra
25:11 等候區(qū)
27:40 等候區(qū)的架構
29:02 國際足聯2014世界杯成績
31:00 回顧和下一步
31:58 NGINX + Lua 表現驚人
33:17 開源軟件開發(fā)
33:55 總結和未來
34:50 問答
19:02 DVR
Juarez:到2013年要出,我們對我們的基礎設施和我們提供的用戶體驗感到很滿意,于是我們開始思考我們還可以為2014年世界杯做些什么其他事情农渊。
我們決定開發(fā)的其中一個功能就是DVR,DVR代表數字視頻錄像機或颊,它可以提供暫停視頻播放砸紊、回放和重新觀看視頻的功能。
要做到基于HLS協議的DVR囱挑,我們只需使用一個更大的播放列表醉顽,正如你之前見到過的那樣,播放列表只是一個排列多個片段的文本文件平挑。對于DVR游添,要將這些幾分鐘的視頻替換成一個完整的比賽視頻的片段。
重新回顧我們的解決方案通熄,我們可以說主要有兩大塊:采集和前端唆涝。兩者之間的接口就是存儲,存儲存放的都是被我們分割后的片段唇辨,分割后的文件通過NGINX提供給用戶訪問請求廊酣。
20:24 DVR的挑戰(zhàn)——故障轉移
因此存儲是一個問題,因為我們沒有故障轉移能力赏枚,如果視頻流停止了亡驰,那么我們不得不重新開始,我們正在使用的EvoStream服務器饿幅,只會刪除播放列表并重新開始一個新的列表凡辱。
如果不提供數字視頻錄像機DVR功能的話,這個不算是一個問題栗恩,因為就算發(fā)生故障用戶也只會看到緩沖提示并且很快就會重新連接透乾,然后視頻流又恢復正常。但是如果你丟失了舊的播放列表,那用戶就不能找回原來的播放點续徽,所以對于DVR蚓曼,我們必須保持所有片段和播放列表的狀態(tài)。
21:06 DVR的挑戰(zhàn)——存儲
我們也有點擔心存儲大小問題钦扭,因為對于單一流來說纫版,一場比賽我們會按照比特率對其進行切分,這里會切分成6種比特率客情,每個比特率對應著不同的質量其弊。用戶根據自己帶寬情況,可以觀看符合條件的任一個資源膀斋,大約每5秒視頻就有4.5兆字節(jié)梭伐,所以對于兩小時的比賽,這將達到大約6G字節(jié)仰担。
我們環(huán)球公司播放兩個同時進行的比賽和其他播放的視頻流糊识,所以我們需要大約40G字節(jié),這并不算很多摔蓝,我們可以將他們全部都放到RAM中赂苗,所以我們決定使用Redis作為視頻的存儲。
Leandro:我們剛剛替換了我們舊的架構贮尉,舊的架構將數據保存到一個目錄下拌滋,而現在我們將數據塊和HLS文件保存到Redis中。
22:11 使用Redis作為數據存儲
Juarez:我們用Python建立了一個守護程序猜谚,它只是一個簡單的腳本败砂,它可以監(jiān)聽文件,當文件被分割成片段后將它們移動到Redis數據庫魏铅。然后我們使用NGINX配合Lua模塊從Redis獲取視頻流列表昌犹,動態(tài)查看播放列表。這項工作緊緊花費了我們一兩天的時間览芳。
Leandro:使用Python感覺很好祭隔,但與此同時我們發(fā)現很難對其進行擴展,我不知道是不是因為我們沒有足夠的經驗路操,對于我們來說疾渴,Python確實很難在將其擴展到多核,所以監(jiān)聽文件變化并保存為HLS協議文件的守護程序給我們帶來很多痛苦屯仗。如果讓我們重新做一遍搞坝,我們可能會選擇另外一種語言,但在當時這是最簡單的解決方案魁袜,現在它仍然在工作桩撮。
Juarez:是的敦第,這個已經成為一個問題,尤其是在巴西大選直播期間店量。
23:20 巴西大選
所以芜果,后來,當我們在直播巴西大選時融师,我們有超過30個同時播放的視頻流右钾,每個視頻流有各自的狀態(tài)。如Leandro所說旱爆,Python腳本成為了一個瓶頸舀射,并且在使用Redis上我們也遇到了問題,因為我們無法把所有這些都放進內存怀伦,所以我們決定從Redis轉向Cassandra脆烟。
需要澄清一下,世界杯直播時我們仍然使用Redis房待,巴西大選時發(fā)生在世界杯之后邢羔,我們認為這個比較有趣所以在這里分享。
24:12 從Redis到Cassandra
除了解決其擴展性問題桑孩,我們沒有必要對守護程序做過多其他的改動张抄。但在前端我們必需為Lua開發(fā)一個新的驅動程序。在那時候我們沒有找到任何NGINX的Lua驅動模塊洼怔,所以我們必須自己編寫。從那時起左驾,越來越多人使用這個模塊镣隶,這讓人看著很高興。
25:11 等候室
我們必須做的另外一件事情是建立一個等候區(qū)诡右,我們沒有使用CDN安岂,我們已經和巴西的幾個互聯網服務提供商合作,我們有兩個數據中心帆吻。
有時用戶可能通過一個低寬帶的ISP連接我們觀看視頻域那,這樣會導致在此ISP上的所有用戶都體驗很不好,所以我們決定創(chuàng)建一個等候區(qū)猜煮,如果太多用戶從同一個連接觀看視頻次员,我們會將他們放進一個隊列里。
Leandro:我們在后面將涉及更多等候區(qū)的相關細節(jié)王带,但首先淑蔚,我們要討論下我們多連接的解決方案,使得用戶能根據IP選擇走哪個線路愕撰。
選播的工作原理是這樣的:你要有一個BGP協議刹衫,該協議用于決定路線醋寝,然后我們要有ISP,由于我們是一個互聯網公司带迟,我們屬于一個自治系統音羞,所以我們可以用公司的ISP進行數據交換。
所以由我們決定線路仓犬,然后我們的ISP將承認這條線路嗅绰,現在,如果在圣保羅附近有很多用戶婶肩,當他們試圖訪問給定的地址是办陷,ISP會智能的將他們的請求路由到最近的PoP。
現在我們可以更加深入地討論等待區(qū)了律歼。
這里我們可以看到ISP Y只有非常低的帶寬連接到我們民镜,所以連接他們的用戶在看直播時將會體驗很差。但他們不會抱怨他們的ISP险毁,他們會通過推特來抱怨我們制圈,這顯然是不理想的,所以我們想出了等候區(qū)方案畔况。
27:40 等候區(qū)的架構
這里我們可以看到ISP Y只有非常低的帶寬連接到我們鲸鹦,所以連接他們的用戶在看直播時將會體驗很差。但他們不會抱怨他們的ISP跷跪,他們會通過推特來抱怨我們馋嗜,這顯然是不理想的,所以我們想出了等候區(qū)方案吵瞻。
27:40 等候區(qū)的架構
我不知道你們是否像我們一樣喜歡足球葛菇,但我們對這個結果不滿意,但這就是生活橡羞。
我非常興奮我們有很多的帶寬供我們使用眯停,該圖大致顯示了我們對比賽進行直播時的幾個峰值,這并不是所有比賽的情況卿泽,但我對這個結果非常滿意莺债。
我們有超過50萬用戶同時在線,并且我們可以很容易地支持更多的用戶签夭。我們本來預計有100萬用戶同時在線觀看齐邦,但我們懷疑真實的在線用戶可能比預期的要少,因為當巴西進行比賽時第租,人們可以從家里觀看比賽侄旬,所以,很多人們更愿意通過電視觀看煌妈,于是通過環(huán)球網觀看的用戶會少很多儡羔。
另一個很酷的數字是某場比賽達到640Gbps宣羊,我認真這是相當不錯的。
既然我們有索倫儀表盤汰蜘,我們可以通過監(jiān)控軟件Graphite進行估算仇冯,結果是所有觀眾觀看的時間總和大致超過1600年,我們有超過四千萬用戶觀看族操。
這里你可以看到我們的平均比特率苛坚,這里面也有我高興的事情,就是我們每個節(jié)點使用了僅僅10%CPU就能達到20G每秒速度色难。
31:00 回顧和下一步
既然我們已經展示了我們的成績泼舱,我覺得是時候回顧一下,并且討論下我們下一步可以為我們的平臺做什么事枷莉。
Juarez:我們在視頻流方面使用了很多NGINX娇昙,我們用它來做傳輸、用來做緩存笤妙。我們開發(fā)了地理定位冒掌、授權、認證等多個模塊蹲盘。
我們也圍繞它內置了很多微服務股毫,我們使用NGINX和Lua用于播放列表的生成,也用于等候區(qū)召衔。我們還有另外一個前面沒有時間提及的系統铃诬,這個系統可以鎖定一個用戶可以擁有并發(fā)會話的數量,但這主要用于封閉播放苍凛,而不是用于像世界杯這樣的直播趣席。
31:58 NGINX + Lua 表現驚人
我們真的很喜歡NGINX和Lua,我們也很高興嘗試了nginScript毫深,但到目前為止,我們更喜歡Lua毒姨,它也是在巴西被創(chuàng)造出來的哑蔫。
Leandro:這個與目前的問題不相關。
Juarez:哈哈弧呐,是的闸迷,這個與目前的問題不相關。我認為我們應該看看技術方面的東西俘枫,我們一直在嘗試并且非常喜愛的框架是Busted腥沽,它在測試驅動開發(fā)方面表現良好,使我們的生活更輕松鸠蚪。
Lua是一個小語言今阳,所以很容易學習师溅,與C語言比起來,我們在開發(fā)UGINX+Lua時體驗更加好盾舌,使用Lua語言開發(fā)起來更快墓臭,然而你仍然可以獲取接近C語言的性能,所以我們對此十分滿意妖谴。
Leandro:Lua至少對我們來說更加容易窿锉,因為我們不是C語言專家。
33:17 開源軟件開發(fā)
我們真的很喜歡NGINX和Lua膝舅,我們也很高興嘗試了nginScript嗡载,但到目前為止,我們更喜歡Lua仍稀,它也是在巴西被創(chuàng)造出來的洼滚。
Leandro:這個與目前的問題不相關。
Juarez:哈哈琳轿,是的判沟,這個與目前的問題不相關。我認為我們應該看看技術方面的東西崭篡,我們一直在嘗試并且非常喜愛的框架是Busted挪哄,它在測試驅動開發(fā)方面表現良好,使我們的生活更輕松琉闪。
Lua是一個小語言迹炼,所以很容易學習,與C語言比起來颠毙,我們在開發(fā)UGINX+Lua時體驗更加好斯入,使用Lua語言開發(fā)起來更快,然而你仍然可以獲取接近C語言的性能蛀蜜,所以我們對此十分滿意刻两。
Leandro:Lua至少對我們來說更加容易,因為我們不是C語言專家滴某。
33:17 開源軟件開發(fā)
Leandro:綜上所述磅摹,從2010年到2014年,我們從RTMP協議轉移到HLS協議霎奢,然后我們推出這個叫DVR的功能户誓。
現在,我們期待奧林匹克運動會的到來幕侠,我們正考慮提供不同類型的方式帝美,例如Dynamic Adaptive Streaming over HTTP。我們可能會改變采集方面關于信號被攝入的方式晤硕,也許要讓它支持4K悼潭。
Juarez:有一件事我們肯定知道的是庇忌,我們將繼續(xù)使用NGINX。
Leandro:是的女责。
34:50 問答
1漆枚、有多少用戶在看巴西隊和德國隊的比賽?詳細情況你知道嗎抵知?
Juarez:我覺得在第三個進球之后墙基,沒有一個觀眾(笑)。不刷喜,只是開個玩笑残制。觀看巴西隊比賽的觀眾很少,因為幾乎所有人都使用電視在看比賽掖疮,而不是通過互聯網初茶,大約有10萬左右的用戶使用播放器觀看。
2浊闪、關于前端NGINX服務器恼布,使用了NGINX Plus機器還是NGINX開源機器。
Leandro:使用了開源機器搁宾,我們使用了社區(qū)中的一款折汞。
Juarez:是的,我們使用了默認的NGINX開源解決方案盖腿,我們也有我們的一些硬件負載均衡器爽待,我們使用它們對跨NGINX多個實例的拆分負載。
3翩腐、你在討論的irqbalance和CPU親和力鸟款,你是怎么意識到這是一個問題的呢?
Juarez:我們注意到的第一件事是我們一直在丟失數據包茂卦,而且我們注意到的第二件事是機器只有一個CPU核在工作何什,我們發(fā)現使用最多CPU的進程是處理網卡軟中斷的那個進程,所以我們首先安裝irqbalance將負載分到其他CPU核上等龙,我們發(fā)現將中斷指定到某個CPU核上性能會更好处渣。
Leandro:所有這一切要歸結到這一事實,那就是我們看到每個節(jié)點的極限是擁有20Gbps傳輸能力而咆,但我們并沒有達到20Gbps霍比,所以我們就認為可能是NGINX存在問題幕袱,或者是其他問題導致的暴备,因為它僅僅用于處理靜態(tài)文件,這個不應該這么難们豌,所以我們開始研究涯捻、故障排除浅妆,然后我們就能夠理解和運用剛才前面講到的優(yōu)化方案。
Juarez:另外一個有趣的數字是障癌,僅僅使用2臺NGINX服務器凌外,我們就可以處理10萬用戶的訪問,這個等同于我們使用50臺Flash媒體服務器處理的用戶量涛浙。