SRS5優(yōu)化:如何將DVR性能提升一倍

Written by 王磊(bluestn).

Summary

SRS支持將直播錄制為VoD文件,在壓測時娃胆,如果流路數(shù)很多承耿,會出現(xiàn)CPU消耗很多的問題及志。

原因是寫入較小視頻包時,SRS使用了write朵诫,由于沒有緩沖能力辛友,導(dǎo)致頻繁的系統(tǒng)調(diào)用和磁盤繁忙。

優(yōu)化方案剪返,可以選擇fwrite和內(nèi)存盤方案废累,可將DVR性能提升一倍以上。

Environments

SRS dvr服務(wù)器配置如下:

  • CPU: INTEL Xeon 4110 雙路16和32線程
  • 內(nèi)存:32G
  • 網(wǎng)卡:10Gb
  • 磁盤:兩塊980G的SSD盤做成RAID0(可用空間共1.8T)
  • 操作系統(tǒng):CentOS 7.6随夸。
  • 流碼率:3Mbps

這里需要說明一下九默,采用SSD盤主要是為了確保磁盤性能足夠,以確保能夠支撐大的并發(fā)壓力宾毒,從而在大并發(fā)壓測的情況下觀察系統(tǒng)性能情況驼修,如果本身磁盤I/O性能比較低下,大量的I/O等待可能導(dǎo)致觀察不到CPU瓶頸的現(xiàn)象诈铛。

另外乙各,在我的測試環(huán)境中,SRS經(jīng)過了多進(jìn)程改造幢竹,能夠支持推流進(jìn)來后自動將不同的流均衡到不同的SRS進(jìn)程上面耳峦,從而能夠充分利用服務(wù)器多核的能力,但是由此得出的結(jié)論同樣適合于單進(jìn)程SRS焕毫。

SRS開啟DVR錄存功能蹲坷,使用如下命令啟動SRS:

env SRS_LISTEN=1935 SRS_MAX_CONNECTIONS=3000 SRS_DAEMON=off SRS_SRS_LOG_TANK=console \
    SRS_HTTP_API_ENABLED=on SRS_VHOST_DVR_ENABLED=on ./objs/srs -e

壓測工具,用srs_bench套件中的sb_rtmp_publish模擬推流客戶端進(jìn)行大并發(fā)量推流模擬邑飒,一臺機(jī)器壓測能力不夠可以開啟多臺機(jī)器進(jìn)行壓測循签。

./objs/sb_rtmp_publish  -i doc/source.200kbps.768x320.flv \
    -c 100 -r rtmp://127.0.0.1:1935/live/livestream_{i}

啟動srs后,用壓測工具進(jìn)行壓測疙咸,觀察測試過程中的CPU县匠、網(wǎng)絡(luò)IO、磁盤IO相關(guān)數(shù)據(jù)撒轮,并進(jìn)行對比乞旦。

write Disk

SRS優(yōu)化前,默認(rèn)的方式就是使用write方法题山,直接寫入磁盤兰粉。測試能支持1000路寫入,CPU跑滿顶瞳。

image-20230107141356751.png

從上圖可以看到玖姑,1000路3M的DVR錄制已經(jīng)將系統(tǒng)的CPU都跑滿了崖蜜,特別需要關(guān)注的是cpu的時間主要消耗在了內(nèi)核空間上面,占了87.5%客峭。

image-20230107142020562.png

用nload查看當(dāng)時的輸入帶寬情況豫领,發(fā)現(xiàn)系統(tǒng)輸入帶寬平均只有2.17Gb,沒有達(dá)到預(yù)期的3Gb的帶寬舔琅,應(yīng)該是CPU負(fù)載過高導(dǎo)致SRS來不及處理網(wǎng)絡(luò)I/O引起的性能下降等恐。

再用perf工具對其中一個srs 進(jìn)程進(jìn)行性能采樣分析,得到下面的火焰圖:

image-20230107142537021.png

可以發(fā)現(xiàn)备蚓,sys_write操作占用的時間消耗是最多的课蔬,對比上面用top看到的內(nèi)核態(tài)消耗的時長占比可以得出的結(jié)論是一致的。

最后看磁盤I/O情況:

image-20230107143617749.png

從上圖看磁盤的利用率沒有到100%郊尝,雖然有一定的波動二跋,但是總體上還是在合理的可以接受的性能范圍內(nèi)。

fwrite Disk

SRS優(yōu)化后流昏,使用fwrite寫入磁盤扎即。錄制1000路流,占用32%的CPU况凉,性能提升一倍以上谚鄙。

image-20230107142837114.png

從上圖可以看到,1000路3M的DVR錄制已經(jīng)將系統(tǒng)的CPU整體來說還有很多空閑(這里說明一下刁绒,部分進(jìn)程的SRS占比高的原因是因為當(dāng)時任務(wù)分配的不夠均衡引起的)闷营。特別值得注意的是本次測試內(nèi)核時間占比大幅下降,只有9.1%知市。

再用nload看網(wǎng)絡(luò)i/o情況傻盟,如下圖:

image-20230107143330746.png

網(wǎng)絡(luò)i/o相當(dāng)平穩(wěn),和預(yù)期的3Gb完全吻合嫂丙。

再看磁盤i/o的情況:

image-20230107143449857.png

從上圖看磁盤的利用率沒有到100%娘赴,雖然有一定的波動,但是總體上還是在合理的可以接受的性能范圍內(nèi)奢入。

最后看火焰圖:

image-20230107145024141.png

系統(tǒng)調(diào)用的時間占比大幅度縮短了筝闹,在上圖幾乎找不到sys_write的位置了媳叨。

write Memory Disk

SRS優(yōu)化前腥光,也可以掛載內(nèi)存盤,使用write寫入內(nèi)存盤糊秆。

需要說明一下武福,由于我手上的服務(wù)器只有32G內(nèi)存,只能分配16G內(nèi)存給內(nèi)存盤使用痘番, 由于內(nèi)存盤比較小捉片,按照3Gb的寫入速度平痰,最多能寫42s的DVR。

采用如下命令掛載內(nèi)存盤:

mount -t tmpfs -o size=16G,mode=0755 tmpfs /data/memdisk

并且修改srs的配置文件將文件寫入到內(nèi)存盤:

env SRS_LISTEN=1935 SRS_MAX_CONNECTIONS=3000 SRS_DAEMON=off SRS_SRS_LOG_TANK=console \
    SRS_VHOST_DVR_DVR_PATH=/data/memdisk/[app]/[stream].[timestamp].flv \
    SRS_HTTP_API_ENABLED=on SRS_VHOST_DVR_ENABLED=on ./objs/srs -e

測試數(shù)據(jù)如下伍纫,占用CPU27%左右:

image-20230107144531967.png

從CPU的情況看宗雇,采用內(nèi)存盤也比較理想,load average只有 7.5莹规,性能也不錯赔蒲。如果不需要錄制大量的流,這種方式也是非常好的良漱。

macOS Test Data

在macOS環(huán)境下舞虱,也做了一組數(shù)據(jù),供參考:

  1. macOS: MacBook Pro, 16-inch, 2019, 12CPU(2.6 GHz 6-Core Intel Core i7), 16GB memory(16 GB 2667 MHz DDR4).
  2. v5.0.132優(yōu)化前: RTMP to HLS, 200 streams, SRS CPU 87%, 740MB
  3. v5.0.133優(yōu)化后: RTMP to HLS, 200 streams, SRS CPU 56%, 618MB
  4. v5.0.132優(yōu)化前: DVR RTMP to FLV, 500 streams, SRS CPU 83%, 759MB
  5. v5.0.133優(yōu)化后: DVR RTMP to FLV, 500 streams, SRS CPU 35%, 912MB
  6. v5.0.133優(yōu)化后: DVR RTMP to FLV, 1200 streams, SRS CPU 79%, 1590MB

Conclusion

從以上4個測試可以得出以下結(jié)論:

  1. 無論ssd盤還是內(nèi)存盤母市,采用fwrite的性能比采用write的性能有明顯的提升矾兜,其主要得益于fwrite內(nèi)置的緩存功能減少了系統(tǒng)調(diào)用的數(shù)量,帶來內(nèi)核時間消耗的減少患久,從而提升了性能椅寺。
  2. 在ssd盤情況下,fwrite的緩沖能力可以大幅度降低對于CPU的消耗蒋失,但是在采用內(nèi)存盤的情況下配并,CPU的消耗雖然也能夠降低,但是不是那么明顯高镐。
  3. 錄制到內(nèi)存盤性能也很好溉旋,如果流路數(shù)不多也可以考慮這種方案。

Note: 之前想當(dāng)然地認(rèn)為用write寫內(nèi)存盤嫉髓,因為系統(tǒng)調(diào)用引起的用戶態(tài)到核心態(tài)的切換還是會導(dǎo)致cpu大量消耗观腊,一樣會導(dǎo)致CPU消耗高居不下,但是事實看到是采用內(nèi)存盤以后cpu消耗明顯下降了算行,是不是可以認(rèn)為系統(tǒng)調(diào)用引起的用戶態(tài)到核心態(tài)的切換消耗實際上并沒有想象的那么大梧油,而是內(nèi)核態(tài)在處理小塊的文件write寫入磁盤的時候還存在著其他因素引起消耗大量的cpu。譬如州邢,因為最終寫入磁盤都是按照扇區(qū)寫入的儡陨,而小塊寫入需要操作系統(tǒng)將這個小塊對齊并填充到一個完整的磁盤扇區(qū),從而引起性能大幅下降量淌,而內(nèi)存盤是不是就不會存在這個問題骗村?由于我自己沒有內(nèi)核方面的經(jīng)驗,所以只能存疑了呀枢,也請懂內(nèi)核的朋友給予指點(diǎn)胚股。

What's Next

在linux環(huán)境中,對于文件進(jìn)行讀寫操作的時候裙秋,我們可以采用libc提供的fread/fwrite系列的一套函數(shù)琅拌,也可以采用操作系統(tǒng)提供的read/write系列的一套系統(tǒng)api函數(shù)缨伊。

對于libc提供的文件讀寫函數(shù),首先它可移植性比較好进宝,因為libc為我們屏蔽了操作系統(tǒng)的底層差異刻坊,在linux、windows等不同的操作系統(tǒng)環(huán)境下面都有標(biāo)準(zhǔn)的接口實現(xiàn)党晋,因此不需要我們?yōu)椴煌牟僮飨到y(tǒng)進(jìn)行適配紧唱。其次,libc提供了帶緩沖功能的讀寫能力隶校,而操作系統(tǒng)底層文件讀寫API卻不提供這種能力漏益,緩沖能力在大多數(shù)情況下能夠為我們帶來文件i/o性能的提升。

當(dāng)然libc的文件讀寫api函數(shù)也存在不足之處深胳,缺少了writev/readv之類的函數(shù)绰疤。不過readv/writev的功能無非就是將多個緩沖區(qū)的內(nèi)容合并成一次批量讀寫操作,而不需要進(jìn)行多次API調(diào)用舞终,從而減少實際物理I/O的次數(shù)轻庆,我想libc沒有提供這類函數(shù)主要也是因為其緩沖功能已經(jīng)能夠?qū)⒈緛硇枰啻蔚男K物理I/O操作合并成了一次更大塊的物理i/o操作,所以就沒有必要再提供readv/writev了敛劝。

不管SRS也好余爆,還是NGINX也好,雖然前者采用st-thread框架的協(xié)程能力來實現(xiàn)網(wǎng)絡(luò)異步i/o夸盟,但是和后者一樣蛾方,最終還是采用epoll事件循環(huán)來實現(xiàn)網(wǎng)絡(luò)異步i/o的,但是對于文件i/o上陕,目前存在的問題是桩砰,無論是write還是fwrite都是同步操作,在磁盤請求比較繁忙的情況下释簿,必然會導(dǎo)致進(jìn)程或者線程阻塞亚隅,從而引起系統(tǒng)并發(fā)性能的下降。

由于操作系統(tǒng)本身不支持epoll異步(linux下的ext4本身沒有實現(xiàn)poll的回調(diào))庶溶,所以寄希望于epoll來實現(xiàn)文件i/o的異步操作是行不通的煮纵。NGINX對于文件異步i/o采用了aio+多線程的方式來實現(xiàn)的,個人感覺是由于和epoll模型來說是一套獨(dú)立的框架偏螺,還是相對比較復(fù)雜行疏。

不過,好在linux在5.1內(nèi)核以后提供了io_uring的異步i/o框架砖茸,它可以統(tǒng)一網(wǎng)絡(luò)i/o和磁盤i/o的異步模型隘擎,并支持buffer IO殴穴,值得我們?nèi)リP(guān)注學(xué)習(xí)一下凉夯,也值得我們后面一起去探討一下未來如何在srs上采用io_uring來實現(xiàn)帶有fwrite一樣的緩沖能力的磁盤i/o的操作货葬,來徹底解決磁盤i/o引起的性能瓶頸的問題。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末劲够,一起剝皮案震驚了整個濱河市震桶,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌征绎,老刑警劉巖蹲姐,帶你破解...
    沈念sama閱讀 218,682評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異人柿,居然都是意外死亡柴墩,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評論 3 395
  • 文/潘曉璐 我一進(jìn)店門凫岖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來江咳,“玉大人,你說我怎么就攤上這事哥放〖咧福” “怎么了?”我有些...
    開封第一講書人閱讀 165,083評論 0 355
  • 文/不壞的土叔 我叫張陵甥雕,是天一觀的道長踩身。 經(jīng)常有香客問我,道長社露,這世上最難降的妖魔是什么挟阻? 我笑而不...
    開封第一講書人閱讀 58,763評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮峭弟,結(jié)果婚禮上赁濒,老公的妹妹穿的比我還像新娘。我一直安慰自己孟害,他們只是感情好拒炎,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,785評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著挨务,像睡著了一般击你。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上谎柄,一...
    開封第一講書人閱讀 51,624評論 1 305
  • 那天丁侄,我揣著相機(jī)與錄音,去河邊找鬼朝巫。 笑死鸿摇,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的劈猿。 我是一名探鬼主播拙吉,決...
    沈念sama閱讀 40,358評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼潮孽,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了筷黔?” 一聲冷哼從身側(cè)響起往史,我...
    開封第一講書人閱讀 39,261評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎佛舱,沒想到半個月后椎例,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,722評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡请祖,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年订歪,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片肆捕。...
    茶點(diǎn)故事閱讀 40,030評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡陌粹,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出福压,到底是詐尸還是另有隱情掏秩,我是刑警寧澤,帶...
    沈念sama閱讀 35,737評論 5 346
  • 正文 年R本政府宣布荆姆,位于F島的核電站蒙幻,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏胆筒。R本人自食惡果不足惜邮破,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,360評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望仆救。 院中可真熱鬧抒和,春花似錦、人聲如沸彤蔽。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽顿痪。三九已至镊辕,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蚁袭,已是汗流浹背征懈。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留揩悄,地道東北人卖哎。 一個月前我還...
    沈念sama閱讀 48,237評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親亏娜。 傳聞我的和親對象是個殘疾皇子焕窝,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,976評論 2 355

推薦閱讀更多精彩內(nèi)容