前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >SRS5优化:如何将DVR性能提升一倍

SRS5优化:如何将DVR性能提升一倍

作者头像
Winlin
发布于 2023-01-09 04:10:31
发布于 2023-01-09 04:10:31
1.4K00
代码可运行
举报
文章被收录于专栏:SRS开源服务器SRS开源服务器
运行总次数:0
代码可运行

Written by 王磊(bluestn).

Summary

SRS支持将直播录制为VoD文件,在压测时,如果流路数很多,会出现CPU消耗很多的问题。

原因是写入较小视频包时,SRS使用了write,由于没有缓冲能力,导致频繁的系统调用和磁盘繁忙。

优化方案,可以选择fwrite(v5.0.133+),或者老版本用内存盘方案,可将DVR性能提升一倍以上。

Environments

SRS服务器配置如下:

  • • CPU:INTEL Xeon 4110 双路16和32线程
  • • 内存:32G
  • • 网卡:10Gb
  • • 磁盘:两块980G的SSD盘做成RAID0(可用空间共1.8T)
  • • 操作系统:CentOS 7.6。
  • • 流码率:3Mbps

这里需要说明一下,采用SSD盘主要是为了确保磁盘性能足够,以确保能够支撑大的并发压力,从而在大并发压测的情况下观察系统性能情况,如果本身磁盘I/O性能比较低下,大量的I/O等待可能导致观察不到CPU瓶颈的现象。

另外,在我的测试环境中,SRS经过了多进程改造,能够支持推流进来后自动将不同的流均衡到不同的SRS进程上面,从而能够充分利用服务器多核的能力,但是由此得出的结论同样适合于单进程SRS。

SRS开启DVR录存功能,使用如下命令启动SRS:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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模拟推流客户端进行大并发量推流模拟,一台机器压测能力不够可以开启多台机器进行压测。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
./objs/sb_rtmp_publish  -i doc/source.200kbps.768x320.flv \
    -c 100 -r rtmp://127.0.0.1:1935/live/livestream_{i}

启动srs后,用压测工具进行压测,观察测试过程中的CPU、网络IO、磁盘IO相关数据,并进行对比。

write SSD Disk

SRS优化前,默认的方式就是使用write方法,直接写入磁盘。测试能支持1000路写入,CPU跑满。

从上图可以看到,1000路3M的DVR录制已经将系统的CPU都跑满了,特别需要关注的是cpu的时间主要消耗在了内核空间上面,占了87.5%。

用nload查看当时的输入带宽情况,发现系统输入带宽平均只有2.17Gb,没有达到预期的3Gb的带宽,应该是CPU负载过高导致SRS来不及处理网络I/O引起的性能下降。

再用perf工具对其中一个srs 进程进行性能采样分析,得到下面的火焰图:

可以发现,sys_write操作占用的时间消耗是最多的,对比上面用top看到的内核态消耗的时长占比可以得出的结论是一致的。

最后看磁盘I/O情况:

从上图看磁盘的利用率没有到100%,虽然有一定的波动,但是总体上还是在合理的可以接受的性能范围内。

fwrite SSD Disk

SRS优化后,使用fwrite写入磁盘。录制1000路流,占用32%的CPU,性能提升一倍以上。

从上图可以看到,1000路3M的DVR录制已经将系统的CPU整体来说还有很多空闲(这里说明一下,部分进程的SRS占比高的原因是因为当时任务分配的不够均衡引起的)。特别值得注意的是本次测试内核时间占比大幅下降,只有9.1%。

再用nload看网络i/o情况,网络i/o相当平稳,和预期的3Gb完全吻合。

再看磁盘i/o的情况,磁盘的利用率没有到100%,虽然有一定的波动,但是总体上还是在合理的可以接受的性能范围内。

最后看火焰图:

系统调用的时间占比大幅度缩短了,在上图几乎找不到sys_write的位置了。

write Memory Disk

SRS优化前,也可以挂载内存盘,使用write写入内存盘。

需要说明一下,由于我手上的服务器只有32G内存,只能分配16G内存给内存盘使用, 由于内存盘比较小,按照3Gb的写入速度,最多能写42s的DVR。

采用如下命令挂载内存盘:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mount -t tmpfs -o size=16G,mode=0755 tmpfs /data/memdisk

并且修改srs的配置文件将文件写入到内存盘:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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

测试数据如下,占用CPU27%左右:

从CPU的情况看,采用内存盘也比较理想,load average只有 7.5,性能也不错。如果不需要录制大量的流,这种方式也是非常好的。

macOS Test Data

在macOS环境下,也做了一组数据,供参考:

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

Conclusion

从以上4个测试可以得出以下结论:

  1. 1. 无论ssd盘还是内存盘,采用fwrite的性能比采用write的性能有明显的提升,其主要得益于fwrite内置的缓存功能减少了系统调用的数量,带来内核时间消耗的减少,从而提升了性能。
  2. 2. 在ssd盘情况下,fwrite的缓冲能力可以大幅度降低对于CPU的消耗,但是在采用内存盘的情况下,CPU的消耗虽然也能够降低,但是不是那么明显。
  3. 3. 录制到内存盘性能也很好,如果流路数不多也可以考虑这种方案。

Note: 之前想当然地认为用write写内存盘,因为系统调用引起的用户态到核心态的切换还是会导致cpu大量消耗,一样会导致CPU消耗高居不下,但是事实看到是采用内存盘以后cpu消耗明显下降了,是不是可以认为系统调用引起的用户态到核心态的切换消耗实际上并没有想象的那么大,而是内核态在处理小块的文件write写入磁盘的时候还存在着其他因素引起消耗大量的cpu。譬如,因为最终写入磁盘都是按照扇区写入的,而小块写入需要操作系统将这个小块对齐并填充到一个完整的磁盘扇区,从而引起性能大幅下降,而内存盘是不是就不会存在这个问题?由于我自己没有内核方面的经验,所以只能存疑了,也请懂内核的朋友给予指点。

What's Next

在linux环境中,对于文件进行读写操作的时候,我们可以采用libc提供的fread/fwrite系列的一套函数,也可以采用操作系统提供的read/write系列的一套系统api函数。

对于libc提供的文件读写函数,首先它可移植性比较好,因为libc为我们屏蔽了操作系统的底层差异,在linux、windows等不同的操作系统环境下面都有标准的接口实现,因此不需要我们为不同的操作系统进行适配。其次,libc提供了带缓冲功能的读写能力,而操作系统底层文件读写API却不提供这种能力,缓冲能力在大多数情况下能够为我们带来文件i/o性能的提升。

当然libc的文件读写api函数也存在不足之处,缺少了writev/readv之类的函数。不过readv/writev的功能无非就是将多个缓冲区的内容合并成一次批量读写操作,而不需要进行多次API调用,从而减少实际物理I/O的次数,我想libc没有提供这类函数主要也是因为其缓冲功能已经能够将本来需要多次的小块物理I/O操作合并成了一次更大块的物理i/o操作,所以就没有必要再提供readv/writev了。

不管SRS也好,还是NGINX也好,虽然前者采用st-thread框架的协程能力来实现网络异步i/o,但是和后者一样,最终还是采用epoll事件循环来实现网络异步i/o的,但是对于文件i/o,目前存在的问题是,无论是write还是fwrite都是同步操作,在磁盘请求比较繁忙的情况下,必然会导致进程或者线程阻塞,从而引起系统并发性能的下降。

由于操作系统本身不支持epoll异步(linux下的ext4本身没有实现poll的回调),所以寄希望于epoll来实现文件i/o的异步操作是行不通的。NGINX对于文件异步i/o采用了aio+多线程的方式来实现的,个人感觉是由于和epoll模型来说是一套独立的框架,还是相对比较复杂。

不过,好在linux在5.1内核以后提供了io_uring的异步i/o框架,它可以统一网络i/o和磁盘i/o的异步模型,并支持buffer IO,值得我们去关注学习一下,也值得我们后面一起去探讨一下未来如何在srs上采用io_uring来实现带有fwrite一样的缓冲能力的磁盘i/o的操作,来彻底解决磁盘i/o引起的性能瓶颈的问题。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-01-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 SRS开源服务器 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
性能优化:SRS为何能做到同类的三倍
性能无疑是服务器的核心能力,几乎每个开源服务器的介绍都是”高性能XXX服务器“。视频服务器由于业务的超复杂度,特别是WebRTC服务器,要做到高性能是非常有挑战的难点。 为何性能很重要?完备的功能需要用性能交换,安全性需要用性能交换,成本需要用性能交换,产品体验需要用性能交换,甚至系统弹性都需要性能交换。有了基础性能,就有了竞争力的资本;基础性能若有问题,举步维艰,想要干点啥都不容易,就像天生羸弱的身子板。 SRS虽然是单进程单线程模型,性能一直都很高,比如: •单进程能跑满千兆或万兆网卡,一般的场景完全能
Winlin
2022/03/18
2.4K0
SRS:流媒体服务器如何实现负载均衡
 点击上方“LiveVideoStack”关注我们 作者:Winlin、Azusachino、Benjamin 编辑:Alex ▲扫描图中二维码或点击阅读原文▲ 了解音视频技术大会更多信息 ---- 当我们的业务超过单台流媒体服务器的承受能力,就会遇到负载均衡问题,一般我们会在集群中提供这种能力,但实际上集群并非是唯一的实现方式。有时候负载均衡还会和服务发现等时髦词汇联系起来,而云服务的LoadBalancer无疑不可回避,因此,这个问题其实相当复杂,以至于大家会在多个场合询问这个问题,我打算系统地阐述
LiveVideoStack
2022/05/25
2K0
SRS:流媒体服务器如何实现负载均衡
比nginx-rtmp高三倍性能的SRS的高性能是个什么球?
SRS单进程能支持9000并发,nginx-rtmp单进程最多支持3000个,单进程的性能SRS是nginx-rtmp的三倍。SRS单进程性能如何做到nginx-rtmp的三倍的?SRS哪几个结构极大提升了性能? 先来看看我们遇到的问题,RTMP协议和HTTP协议是又很大不同的。nginx在分发HLS,即m3u8文本文件和ts视频文件时,对所有连接发送的都是同一个内容,甚至可以调用sendfile让内核自己发fd去,nginx服务器自己要干的事情很少了;如果nginx必须把每个ts的内容读出来,修改里面某些
Winlin
2022/03/18
8150
云SRS:支持云录制,直播中可回看
云录制是心心念念了很久的一个功能,因为直播的内容需要沉淀,就必须录制下来编辑,剪辑和处理后转短视频可以再分发。 另外,发现支持云录制后,直播中也可以回看了,方便直播来晚的同学看之前的内容。也就是俗称的直播时移,当然是比较简单的时移,复杂的还需要有节目单。 Why 为何云录制这么重要?列举几个我知道的原因,不限于这些原因,应用会更广泛。 •直播内容需要沉淀,特别是有价值的内容,录制到本地磁盘会有磁盘满和丢失问题,而云录制不存在这个问题,无限空间永不丢失。•监控上云场景,除了H5观看,录制是刚需。监控内容可以再
Winlin
2022/03/18
4.1K0
最佳实践:如何扩展你的SRS并发能力?
当我们用SRS快速搭建了视频服务,业务也开始上线运行了,很快就会遇到一个问题:如何支持更多的人观看?如何支持更多的人推流?这本质上就是系统的水平扩展能力,SRS当然是支持的,而且有多种扩展的方法,这篇文章就就详细分析各种扩展的方案,以及各种方案的应用场景和优缺点。 从哪里开始 我们看最简单的视频服务,推一个流,只有一个播放器消费流,我们只需要一个SRS Origin源站服务就可以: listen              1935;max_connections     1000;vhost __
Winlin
2022/03/18
1.8K0
io_uring 从原理到动手实践 part1: 使用系统调用接口实现 cat 程序
感觉目前看到介绍 io_uring 的文章还是比较少,大部分都集中在对其原理性的介绍和简单的对官方文档的翻译,真正结合实际的例子还是比较少。本文翻译整理自一篇博客:
云微
2023/02/24
1.4K0
io_uring 从原理到动手实践 part1: 使用系统调用接口实现 cat 程序
腾讯云音视频与SRS开源生态
自由与开源软件的理念,从不解、争议、接受到如今如火如荼,经历了长期的历程。国内开源软件起步较晚,但进展迅速。腾讯经过几年的开源协同运动,也取得了不少成绩。其中,腾讯云音视频在FFmpeg、SRS等重要多媒体开源社区的贡献,颇具代表性。 SRS是开源实时视频服务器、全球流服务器中Star最多也最活跃的开源项目,主要应用在直播、WebRTC、安防和交通等领域,支持常用的流媒体协议和转换,以好用易用赢得了全球开发者的良好口碑。开箱即用的云SRS开源音视频方案赋能众多行业创造了新的可能。同时,SRS由工信部木兰开源
腾讯云音视频
2023/04/11
2.2K0
腾讯云音视频与SRS开源生态
OSSRS搭建rtmp推流服务器
文中测试视频:https://pan.baidu.com/s/1Cs9bULQ26zmDjbNqiIyUow 密码:q839
西里国际站
2023/04/18
4.2K0
SRS 6封版:GB支持外部SIP服务
实际上SRS 5.0已经支持了GB28181协议,不过只支持了内嵌的SIP服务,而不支持外部的SIP服务,这导致实际上很难把GB大规模应用起来。
Winlin
2024/07/30
8421
SRS 6封版:GB支持外部SIP服务
SRS: Load Balancing Streaming Servers
Load Balancing Streaming Servers Written by Winlin[1], Azusachino[2], Benjamin 程序员确实应该要能看英文和写英文,支持陶老板说的《要做研发高手,就是必须能看英文、写英文》,所以写了一篇试试。大家先试试看看吧,看看能不能看懂,搞不好大家都能看懂;万一看不懂,我们会再翻译成中文;请评论区留言哦。 When our business workloads exceed streaming-server capacity, we have
Winlin
2022/05/17
7790
SRS: Load Balancing Streaming Servers
音视频技术开发周刊 | 279
每周一期,纵览音视频技术领域的干货。 新闻投稿:contribute@livevideostack.com。 ---- 基于NeRF的APP上架苹果商店!照片转3D只需一部手机 这个名叫Luma AI的“NeRF APP”,正式上架App Store后爆火。 反 AiArt 运动中两件匪夷所思的蠢事 Reddit 论坛上,拥有两千多万加入者的 ART 版块 reddit.com/r/Art,永久封禁了一名数字艺术家。理由是他违反版规,在该版上发布了一幅疑似 “AI 生成”的作品。这名被封禁的越南插画师 B
LiveVideoStack
2023/02/23
6250
音视频技术开发周刊 | 279
SRS:webrtc_to_rtmp详解
SRS(Simple Realtime Server),自我开始做音视频行业开始,就有人力推给我的一个开源库,虽然我到现在还是音频领域的入门出徘徊,但也积攒了一些对srs的使用经验。
何其不顾四月天
2024/07/31
4700
SRS、EasyDarwin、ZLMediaKit、Monibuca对比分析
目前市面上有很多开源的流媒体服务器解决方案,常见的有SRS、EasyDarwin、ZLMediaKit和Monibuca等,我们应该怎么选择呢?
liuzhen007
2021/02/06
28.8K1
PostgreSQL 性能优化全方位指南:深度提升数据库效率
在现代互联网应用中,数据库性能优化是系统优化中至关重要的一环,尤其对于数据密集型和高并发的应用而言,PostgreSQL(以下简称PG)凭借其丰富的特性和强大的功能,成为很多企业的首选。然而,随着数据规模的扩展和查询复杂度的提升,PostgreSQL的性能问题逐渐显现。本文将详细介绍PostgreSQL性能优化的各个方面,涵盖硬件调优、数据库配置、索引使用、查询优化等内容,帮助你全方位提升数据库的效率。
用户11404404
2024/12/13
7970
CentOS7下利用SRS搭建直播流媒体服务器
SRS is a RTMP/HLS/WebRTC/SRT/GB28181 streaming cluster, high efficiency, stable and simple.
yuanfan2012
2020/09/10
4.3K0
vSAN架构解析与6.7功能介绍
内容来源:2018 年 7 月 17 日,VMware大中华区原厂高级技术讲师史峻在“VMware直播分享 第二期”进行《vSAN架构解析与6.7功能介绍》演讲分享。IT 大咖说经主办方和演讲者审阅授权转发。
IT大咖说
2018/07/30
2.3K0
vSAN架构解析与6.7功能介绍
国产开源流媒体SRS4.0对视频监控GB28181的支持
1. SRS最大的特点就是简单,表现在代码架构简单,实现简单,部署简单,运维简单;
潇湘落木
2020/11/12
8.1K1
国产开源流媒体SRS4.0对视频监控GB28181的支持
【Linux网络#17】五种 IO 模型
总结: 网络性能优化的核心是 减少 I/O 等待时间 和 提升 I/O 吞吐量。
IsLand1314
2025/03/10
1670
【Linux网络#17】五种 IO 模型
Monibuca 中的内存复用
Go语言本身具备出色的性能,然而在流媒体服务器这种CPU密集+IO密集的双重压力下,GC带来的性能损失是最主要的矛盾。而减少GC的操作最直接的办法就是减少内存申请,多多复用内存。本文将围绕内存复用这个主题,把M7S中相关技术原理讲解一遍,也是M7S性能优化的历程。
我不是码神
2023/10/16
3720
Monibuca 中的内存复用
Nginx引入线程池 性能提升9倍
正如我们所知,NGINX采用了异步、事件驱动的方法来处理连接。这种处理方式无需(像使用传统架构的服务器一样)为每个请求创建额外的专用进程或者线程,而是在一个工作进程中处理多个连接和请求。为此,NGINX工作在非阻塞的socket模式下,并使用了epoll 和 kqueue这样有效的方法。
哲洛不闹
2018/09/18
8690
Nginx引入线程池 性能提升9倍
推荐阅读
相关推荐
性能优化:SRS为何能做到同类的三倍
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验