2017年4月18日和19日,F(xiàn)acebook在San Jose召開了一年一度的F8大會,本次大會通過Facebook Live進行了直播。Designing for Scale的博主Wissam Abirached通過Facebook Live觀看了這屆F8大會,他對Facebook Live是如何擴展以支持F8的這個問題產生了十分濃厚的興趣,因此撰寫了一篇名為《How Facebook Live Scales》的文章,由此也引出了Facebook Live的很多細節(jié)。
早在2015年底,F(xiàn)acebook的工程師就在《Under the hood: Broadcasting live video to millions》一文中介紹了Faceook Live的一些細節(jié)。Facebook擁有龐大的用戶群,在面對流量尖刺的同時,還要盡可能降低延時以帶來更強的參與感,他們遇到了什么問題,又是如何解決的呢?
首先是“驚群問題”(Thundering Herd Problem),它會造成延時、丟幀,甚至是掉線,為了避免直播流服務器(Live Stream Server)被大量請求沖垮,F(xiàn)acebook構建了由直播流服務器、源服務器(Origin Server)和邊緣緩存(Edge Cache)組成的三層結構。用戶訪問最近的邊緣緩存,邊緣緩存負責回源,源服務器向直播流服務器取得實際的內容。
如果某個邊緣緩存負載過高,負載均衡器會將請求重定向到離該節(jié)點最近的另一個尚可提供服務的邊緣緩存上,負載均衡器能夠預測目標節(jié)點的負載情況,這是一個非常實用的功能。
在這種情況下,仍然會有1.8%的請求透過邊緣緩存落到源服務器上,在海量請求下,1.8%也是一個很大的數(shù)字。為了應對這個問題,邊緣緩存只會讓第一個請求回源,其他的相同請求則放在一個隊列中,等第一個請求的結果返回了,它們也就不用再回源了。源服務器上也有類似的請求合并回源處理機制。Wissam Abirached在文章中提到,如果使用Nginx,可以將proxy_cache_lock設置為on開啟請求合并功能。
另一方面,為了讓直播的感受更加實時,F(xiàn)acebook使用RTMP流協(xié)議每隔2到3秒就傳輸一次數(shù)據(jù),RTMP通過播放器與服務端的TCP長連接將音頻與視頻數(shù)據(jù)連續(xù)不斷地推送給用戶。在RTMP中,音頻流與視頻流是分開的,但都以4KB為單位,推模式與小數(shù)據(jù)塊的結合,大大降低了延時,給用戶帶來更流暢的體驗。
值得一提的是,國內的一些直播服務提供商也擁有與Facebook類似的架構,針對海量請求做了各種優(yōu)化,可以說不亞于Facebook。比如,七牛云白順龍的《移動CDN及直播性能優(yōu)化》(這篇《七牛直播云性能優(yōu)化實踐》博客的內容也是一樣的),又拍云黃慧攀的《云直播系統(tǒng)架構與實施》,兩者都提到了類似Facebook的多層服務器結構和網絡智能調度系統(tǒng)(可能大家在節(jié)點部署上略有不同,畢竟服務的目標更多是在國內),能夠在極大程度上保證用戶的體驗。大家也都對直播常用的協(xié)議進行了說明,介紹了RTMP、HLS和HTTP-FLV,以及它們分別適用的場景,在各自系統(tǒng)中的位置。
此外,上述兩個演講中還提到了一些其他的優(yōu)化,比如GOP緩存的權衡、多碼率支持和HTTP-DNS等等,相信Facebook也有類似的處理。
如果您對Facebook Live的更多細節(jié)感興趣,可以看看Facebook的Federico Larumbe在@Scale 2016上的這個演講。在直播盛行的今天,相信一定有很多讀者從事直播相關的工作,也歡迎大家分享自己的直播系統(tǒng)優(yōu)化經驗。
本文永久更新鏈接地址:http://www.linuxidc.com/Linux/2017-05/143582.htm