最佳实践:如何扩展你的SRS并发能力?

作者:忘篱
来源:SRS 开源服务器

最佳实践:如何扩展你的SRS并发能力?

从哪里开始

我们看最简单的视频服务,推一个流,只有一个播放器消费流,我们只需要一个 SRS Origin 源站服务就可以:

listen              1935;
max_connections     1000;
vhost __defaultVhost__ {
}

Remark:SRS 启动时默认就是 Origin 源站模式。

假设我们把 SRS 源站部署在杭州阿里云的 ECS 上,主播使用 OBS 在上海推流,观众在北京观看,如下图所示:
最佳实践:如何扩展你的SRS并发能力?

Remark:虽然地域较远,但 ECS 是 BGP 带宽,效果其实不错的。

Remark:虽然只有一台服务器,SRS 能支持 3K 个推流流,或者 7.5K 个播放,详细参考 SRS 的性能报告。

Note:可能你实测的数据不同,以上数据是在特定环境的结果,包括:流的码率,服务器 CPU 主频和带宽能力,选择的协议,SRS 的版本等差异影响。

如何支持更多的播放

不管是移动端 Native 播放的 RTMP/FLV,还是移动端浏览器播放的 HLS,或者 WebRTC 播放器,所有的视频服务最终是有播放的,在会议中叫订阅或与会者,本质上就是消费视频流。

在直播场景中,一个流会被非常多的播放器消费,比如一个球赛、国庆活动、一个电商大 V 的直播,直播对于播放的扩展能力是核心诉求,这也是 CDN 解决的关键问题之一,当然我们使用 SRS 也可以构建这样的能力,区别在于 CDN 的带宽成本会更低,而 SRS 一般部署在 BGP 云机房,网络稳定性更高但成本更高。

在会议或在线教育中,一个流可能不会被那么多人消费,比如一个 100 人的会议,可能一个视频流只会被另外 99 个人消费,如果在 MCU 模式下这些流会被合并后被其他与会者消费,如果开启语音激励或者用户选择,可能只有说话的人会被其他人消费,本质上和直播的连麦很像,在视频服务中大部分是不对等的情况,推流的少播放的多或者多太多。

在监控或者一对一聊天场景中,一个流会被少量的播放器消费,一对一就是一个播放器消费,监控可能更特殊些可能没有人消费只有在某些时候才会被消费,比如 GB28181 使用 SIP 协议,在有播放器消费流时才邀请摄像头把流送上来。

SRS 支持 Edge 边缘服务器,来扩展源站的支持播放的能力。我们将源站部署在阿里云杭州 ECS 上,主播从上海使用 OBS 推流,杭州我们需要支持 4K 播放,北京我们需要支持 8K 播放,我们就可以在杭州和北京部署 SRS 边缘服务器,如下图所示:
最佳实践:如何扩展你的SRS并发能力?

Remark:播放器如何找到对应的SRS边缘服务器,可以新增一个调度服务器,播放器请求调度服务器的HTTP API,调度返回边缘服务器的IP就可以。

Remark:调度服务也可使用DNS服务,现在云厂商一般也提供DNS服务,可以根据播放所在的区域,解析到对应的IP上。

这个结构是可以水平扩展的,一个 SRS 源站,最多可以支持 7K 个边缘节点。如果 7K 个节点不够,还可以使用多级边缘服务器,完成无数个节点的扩展能力。

SRS 如何用多个 CPU

SRS 使用单进程单线程模型,可以避免线程切换的消耗,也可以避免并发和竞争条件,所以默认情况下 SRS 只能使用一个 CPU,也就是虽然机器有 4 个 CPU 最高能跑到 400%,但 SRS 只能用一个 CPU 最高只能跑 100%。

当然这是默认情况,是有解法的:

  • 降低机器的 CPU 个数,比如申请 ECS 时只申请 2 个 CPU 的,这样就不会有多个 CPU 的烦恼了。

  • 使用 K8S 和 Docker 虚拟化资源,使用 Docker 跑 SRS,这样每个 SRS 最多用 100%,但可以跑多个 Docker。

  • 使用 SRS 的多进程和集群方案,如果确实需要使用多 CPU 能力,还是会有方案的,下面详细讲这种。

我们先考虑单个源站服务器如何使用多进程,比如 4CPU,单个 SRS 只能支持 7K 播放,我们可以扩展 4 倍能力到 28K 播放。单进程的部署结构如下:
最佳实践:如何扩展你的SRS并发能力?

源站的多进程部署结构如下:
最佳实践:如何扩展你的SRS并发能力?

Remark:这种部署结构只能扩展源站的播放能力,因为新增的是 Edge 服务器,流最终还是要回源到 Origin 服务器。

当然这种结构如果将源站单独部署到一台服务器后,就变成了上一章所讲的结构了,差异在于上一章的每个 Edge 服务器还是单进程,没有使用 Reuse Port 扩展多进程能力,这两个结构是可以结合起来用的,如下图所示:
最佳实践:如何扩展你的SRS并发能力?

Remark:在这个结构中,每个Edge服务器上也部署了多个SRS Edge进程,这样可以将边缘服务器的多核能力用起来。

到目前为止,我们更多关注的是播放的扩展能力,如何扩展推流能力呢?下面开始讲这个。

如何收更多的流

推流能力,一般也叫收流的能力,因为推流就是指客户端将流推送到 SRS,而从 SRS 角度看就是把客户端的流收了提供服务。

在 SRS 的角色中,Edge 主要解决播放或下行的扩展能力,而 Origin 则是解决上行或推流的扩展能力。

Origin 源站提供了多个方案来实现扩展,按照上面的场景,我们假设杭州有 3K 的主播,为了业务稳定性我们不能部署一个 Origin 服务器来支持 3K,这会导致 CPU 跑得比较高,而且一般源站还需要录制或转 HLS,需要预留一些 CPU 出来做其他业务。

SRS 支持 Vhost,可以将流分成不同的逻辑域,比如 3K 个流,我们可以分成 2 个 Vhost,这样每个 Vhost 的流只有 1.5K,可以推流到 2 个源站,如下图所示:
最佳实践:如何扩展你的SRS并发能力?

Remark:我们用两个颜色区分了两个 Vhost,对于 Edge 来说不同的 Vhost 可以回源到不同的 Origin,所以可以从同一个 Edge 播放不同的 Vhost 的流。

Note:图中播放器连接的是 Edge 服务器,实际上推流也可以推到边缘的,没有必要必须推源站。

Note:建议客户端连接 Edge,而不直接连接 Origin,这样可以获得更好的一致性,比如播放时只需要加 Query 参数指定 vhost 就可以,而不用关心 Origin 会根据不同 Vhost 有不同的地址。

Note:Vhost 的优势是完全独立的源站,不会互相干扰,在客户端指定了 vhost,相当于在客户端做了负载均衡,系统结构比较简单,劣势是业务是有感知的。

如果业务不按照 Vhost 区分,或者一个 Vhost 的流也非常多,那么 SRS 提供了 Origin Cluster 源站集群扩展源站,如下图所示:
最佳实践:如何扩展你的SRS并发能力?

Remark:两个 Origin 服务器之间会互相查询流,若 Edge 请求的流不在本源站上,会将 Edge 定向到有流的 Origin,详细请参考 OriginCluster 的 WIKI 说明。

Note:同样的,建议不要直接推流到 Origin,而推流到 Edge。

Note:源站集群优势是部署时比较简单,不需要根据业务配置 Vhost,劣势是源站之间是需要互相访问的。

值得说明的是,由于源站是流的最终所在地,所以他本质上是有状态的,两个源站并不是完全等价的。而边缘可以认为是合并回源的代理,两个 Edge 是没有差别的,它们并没有存储流的信息,都是通过源站获取流。因此,推流的扩展能力,比播放的扩展能力,对系统的挑战是更大的。

在监控领域,可能有 10 万或 100 万摄像头,如果需要把这些摄像头的流全部推送到服务器处理,那这个量级还是非常的大的。一般会在本地处理后,再把流送到服务器,比如图像识别到摄像头有活动,可以把信息送到服务器,需要观看这个流后,再把流送到服务器。

不建议的做法

发现还是会有少对 SRS 的误用,这里列出来一些不建议的做法:

  • 不建议 Forward,Forward 并不是扩展集群的能力,而是把流复制一份给别的系统,一般在系统迁移,或者需要两个系统有同样的流时,才需要用 Forward。

  • 不建议在边缘切 HLS 和 DVR,因为边缘没有流,所以无法切片 HLS,只能在有播放 RTMP 或 FLV 时,才会去把流拉到边缘。所以如果边缘做 HLS 切片,会发现播放 HLS 前要播放 RTMP,这是很奇怪的做法。

  • 不建议把所有业务放一台服务器,比如有些流是指需要出 HLS,有些流只需要 DVR,有些流只需要 FLV,那么这些流就应该分成不同的 Vhost,送到不同的源站处理,这样可以避免互相干扰。比如 HLS 和 DVR 需要写磁盘,可能会导致 IO 负载高,可能会影响到 FLV 流。

  • 不建议把业务做到 SRS 中,比如无人播放时停止推流,那么不应该让 SRS 断开连接,而应该业务系统观察到无人播放时,通知推流停止推流。这样可以让 SRS 集中在流媒体处理,而不是因为业务代码 Crash。

  • 不建议 Edge 前面挂 F5 或 Proxy,Edge 本身就是 Proxy,再挂个 Proxy 意欲何为呢,流量一点都没有节省。有些可能是为了让客户端访问的 IP 保持一致,那么可以用 DNS 域名方式,这样客户端看到的都是一个 DNS 名称,会解析成不同的 Edge 的 IP。

还有些值得特别说明的:

  • 以上扩展能力,可以组合使用,比如源站可以是单个 SRS,也可以用一个 Origin 和多个 Edge 组成小集群源站,再让 Edge 使用 Reuse Port 对外就是一个 IP 和端口。

  • Edge 拉流可以支持多个协议,对于扩展同样是适用的,比如 WebRTC 也可以使用 Edge 扩展播放的能力,同样 GB28181 推流后播放的协议和源站架构无关。但目前 WebRTC 推流和源站集群的能力还在开发中。

  • 一般来说,Edge 就是为了扩展播放的能力,但推流也可以走 Edge 这是为了让推流的地址更简单,而不用关注 Origin 的部署结构。一般来说,源站 Origin 是为了扩展收流的能力,但对于 WebRTC 这种结构,可能没有固定的 Origin 和 Edge,它可能需要的是一种切换角色的能力。

「视频云技术」你最值得关注的音视频技术公众号,每周推送来自阿里云一线的实践技术文章,在这里与音视频领域一流工程师交流切磋。

最佳实践:如何扩展你的SRS并发能力?

上一篇:OpenGL 学习系列---坐标系统


下一篇:当SRS遇到K8s:快速构建高并发直播集群