流媒體服務器(視頻服務器)實現超大併發的解決方案

1、概述

流媒體服務器(視頻服務器)是在線視頻應用的核心繫統,用於支持海量大併發的視頻播出服務,實現將視頻存儲、視頻轉碼、協議複用、大併發播出等的工做集中處理,業務系統能夠只關注業務細節而不用再去處理與視頻相關的諸多技術細節,從而實現提升項目實施效率、下降項目實施風險的目標。
那麼流媒體服務器是如何實現高負載大併發的呢,其中有幾項技術細節相當重要,下面以流媒體服務器 NTV Media Server G3 所採用的技術細節爲例來講明。linux


2、關鍵技術

一、epoll技術

epoll是Linux內核爲處理大批量文件描述符而做了改進的poll,是Linux下多路複用IO接口select/poll的加強版本,它能顯著提升程序在大量併發鏈接中只有少許活躍的狀況下的系統CPU利用率。另外一點緣由就是獲取事件的時候,它無須遍歷整個被偵聽的描述符集,只要遍歷那些被內核IO事件異步喚醒而加入Ready隊列的描述符集合就好了。epoll除了提供select/poll那種IO事件的水平觸發(Level Triggered)外,還提供了邊緣觸發(Edge Triggered),這就使得用戶空間程序有可能緩存IO狀態,減小epoll_wait/epoll_pwait的調用,提升應用程序效率。
epoll的主要優點包括:
1)支持一個進程打開大數目的socket描述符
select 最不能忍受的是一個進程所打開的FD是有必定限制的,由FD_SETSIZE設置,默認值是1024。對於那些須要支持的上萬鏈接數目的IM服務器來講顯然太少了。這時候你一是能夠選擇修改這個宏而後從新編譯服務器代碼,不過資料也同時指出這樣會帶來網絡效率的降低,二是能夠選擇多進程的解決方案(傳統的Apache方案),不過雖然linux上面建立進程的代價比較小,但仍舊是不可忽視的,加上進程間數據同步遠比不上線程間同步的高效,因此也不是一種完美的方案。不過 epoll則沒有這個限制,它所支持的FD上限是最大能夠打開文件的數目,這個數字通常遠大於2048,舉個例子,在1GB內存的機器上大約是10萬左右,具體數目能夠cat /proc/sys/fs/file-max查看,通常來講這個數目和系統內存關係很大。
2)IO效率不隨FD數目增長而線性降低
傳統的select/poll另外一個致命弱點就是當你擁有一個很大的socket集合,不過因爲網絡延時,任一時間只有部分的socket是「活躍」的,可是select/poll每次調用都會線性掃描所有的集合,致使效率呈現線性降低。可是epoll不存在這個問題,它只會對「活躍」的socket進行操做---這是由於在內核實現中epoll是根據每一個fd上面的callback函數實現的。那麼,只有「活躍」的socket纔會主動的去調用 callback函數,其餘idle狀態socket則不會,在這點上,epoll實現了一個「僞」AIO,由於這時候推進力在os內核。在一些 benchmark中,若是全部的socket基本上都是活躍的---好比一個高速LAN環境,epoll並不比select/poll有什麼效率,相反,若是過多使用epoll_ctl,效率相比還有稍微的降低。可是一旦使用idle connections模擬WAN環境,epoll的效率就遠在select/poll之上了。
3)沒有使用mmap加速內核與用戶空間的消息傳遞編程

二、sendfile技術

Linux系統的sendfile 函數實如今兩個文件句柄之間直接傳遞數據,避免了內核緩衝區和用戶緩衝區之間數據的拷貝,操做效率很是高,稱爲零拷貝。傳統的編程,從文件到網卡發送文件數據,須要在兩個緩衝區之間拷貝數據,使用sendfile函數,能夠直接經過共享文件指針來實現。linux系統開發指南是這樣描述的:
「sendfile() copies data between one file descriptor and another.Because this copying is done within the kernel, sendfile() is more efficient than the combination of read(2) and write(2), which would require transferring data to and from user space.」
原型定義以下:緩存

#include<sys/sendfile.h>
ssize_t sendfile(int out_fd,int in_fd,off_t*offset,size_t count);

三、文件指針複用

對於視頻點播應用,理想的狀況是在大併發狀況下不少用戶在訪問有限的數個熱點資源,這時候優化的空間就很大。若是爲每一個用戶請求單獨打開一個文件句柄,那麼就沒法在進行文件指針複用,磁盤IO和內存會顯著增高。若是咱們只爲每一個相同文件打開一個句柄,多個用戶請求一個文件時進行讀指針複用,狀況就會好的多。另外,這個打開的文件會被加載到內存裏,衆多的讀操做只是在內存中進行,而不是進行磁盤讀寫,這個操做對消除磁盤IO瓶頸起到了關鍵做用。服務器

3、超大併發的處理

當併發量超過1萬,達到數萬甚至數十萬時,在單機上進行優化的手段就顯得力不從心了,這時候須要從網絡架構和集羣的較多去考慮問題。NTV Media Server G3有兩種方案處理海量併發,一是集羣方案,經過多臺服務器之間創建負載均衡來實現大併發;二是CDN加速方案,經過與CDN系統創建加速配置關係,將負載轉移給CDN,實現全球範圍的大併發播出。 固然,CDN與流媒體服務器的負載已經沒有太多關係,是另一個能夠獨立探討的技術話題。網絡

相關文章
相關標籤/搜索