SRS:流媒体服务器如何实现负载均衡

当我们的业务超过单台流媒体服务器的承受能力,就会遇到负载均衡问题,一般我们会在集群中提供这种能力,但实际上集群并非是唯一的实现方式。有时候负载均衡还会和服务发现等时髦词汇联系起来,而云服务的LoadBalancer无疑不可回避,因此,这个问题其实相当复杂,以至于大家会在多个场合询问这个问题,我打算系统地阐述这个问题。 如果你已经知道了以下问题的所有答案,并且深刻了解背后的原因,那么你可以不用看这篇文章了:

  • SRS是否需要Nginx、F5或HAProxy做流代理?不需要,完全不需要,这样是完全误解了流媒体的负载均衡。而HTTPS我们却建议这么做,同时为了减少对外服务的IP又建议用云LoadBalancer。

  • 如何发现SRS边缘节点?如何发现源站节点?对于边缘,通常DNS和HTTP-DNS都可以;而源站是不应该直接暴露给客户端直接连接的。

  • WebRTC在服务发现上有什么区别?由于CPU性能损耗更大,负载均衡的阈值更低;在单PeerConnection时流会动态变化,导致更难负载均衡;移动端UDP的切网和IP漂移,会引入更多问题。

  • DNS和HTTP-DNS哪个更合适作为流媒体服务器的服务发现机制?肯定是HTTP-DNS,因为流媒体服务器的负载变化,比Web服务器的变化更大,考虑新增1K的客户端对于两种不同服务器的负载影响。

  • 负载均衡是否只需要考虑如何降低系统负载?首要目标是考虑降低系统负载,或者防止系统过载导致质量问题甚至崩溃;同时在同等负载时,也需要考虑就近服务和成本因素。

  • 负载均衡是否只能靠增加一层服务器?一般大型的CDN分发系统,明显是分层的,无论是静态的树设计,还是动态的MESH设计,在流的传输上都是靠分层增加负载能力;同时,还能通过端口重用(REUSEPORT)方式,用多进程方式增加节点的负载而不会增加层。

  • 负载均衡是否只能使用集群方式实现?集群是基本的增加系统容量的方式,除此之外,也可以通过业务分离配合Vhost实现系统隔离,或者通过一致性hash来分流业务和用户。

好吧,让我们详细聊聊负载和负载均衡。 What is Load? 在解决系统均衡问题时,首先我们看看什么是负载?对于服务器来说,负载就是因为有客户端的访问,而导致的资源消耗上升。当资源消耗出现严重不均衡,可能会导致服务不可用,比如CPU跑满了,所有客户端都会变得不正常。 对于流媒体服务器而言,就是流媒体客户端导致的服务器资源消耗。一般我们会从服务器资源消耗角度度量系统负载:

  • CPU: 服务器消耗的CPU,一般我们称CPU消耗较多的为计算密集型场景,而把网络带宽消耗较多的称为IO密集型场景。直播场景一般属于IO密集型场景,CPU一般不会首先成为瓶颈;而在RTC中却不是,RTC是IO和计算都很密集,这是非常大的差异。

  • 网络带宽: 传输流媒体时需要消耗网络带宽,也就是上文介绍的IO密集型场景。流媒体肯定是IO密集型场景,所以带宽一定是重要的瓶颈。而有些场景比如RTC同时还是计算密集场景。

  • 磁盘: 如果不需要录制和支持HLS,那么磁盘就不是重要的瓶颈,如果一定开启录制和HLS,那么磁盘将变得非常关键,因为磁盘是最慢的。当然由于现在内存较多,所以一般我们采用挂内存盘的方式避免这个问题。

  • 内存: 相对而言,内存是流媒体服务器中消耗较少的资源,尽管做了不少Cache,但是内存一般还是不会首先达到瓶颈。所以一般内存也会在流媒体服务器中大量用作Cache,来交换其他的资源负载,比如SRS在直播CPU优化时,用writev缓存和发送大量数据,就是用高内存换得CPU降低的策略。

当负载过高,会有什么问题?负载过高会导致系统直接出现问题,比如延迟增大,卡顿,甚至不可用。而这些负载的过载,一般都会有连锁反应。比如:

  • CPU: CPU过高会引起连锁反应,这时候意味着系统无法支持这么多客户端,那么会导致队列堆积,从而引起内存大量消耗;同时网络吞吐也跟不上,因为客户端无法收到自己需要的数据,出现延迟增大和卡顿;这些问题反而引起CPU更高,直到系统崩溃。

  • 网络带宽: 若超过系统的限定带宽,比如网卡的限制,或者系统队列的限制,那么会导致所有用户都拿不到自己需要的数据,出现卡顿现象。另外也会引起队列增大,而处理堆积队列,一般需要消耗CPU,所以也会导致CPU上升。

  • 磁盘: 若超过磁盘负载,可能会导致写入操作挂起。而在同步写入的服务器,会导致流无法正常传输,日志堆积。在异步写入的服务器,会导致异步队列堆积。注意目前SRS是同步写入,正在进行多线程异步写入。

  • 内存: 超过内存会OOM,直接干掉服务器进程。一般内存主要是泄露导致的缓慢上涨,特别是在流很多时,SRS为了简化问题,没有清理和删除流,所以若流极其多,那么内存的持续上涨是需要关注的。

由此可见,系统的负载,首先需要被准确度量,也就是关注的是过载或超载(Overload)情况,这个问题也需要详细说明。 What is Overload? 超过系统负载就是超载或过载(Overload),这看起来是个简单的问题,但实际上却并不简单,比如:

  • CPU是否超过100%就是过载?不对,因为一般服务器会有多个CPU,也就是8个CPU的服务器,实际上能达到800%。

  • 那CPU是否不超过总CPU使用率,比如8CPU的服务器不超过800%就不会过载?不对,因为流媒体服务器不一定能用多核,比如SRS就是单核,也就是它最多跑100%。

  • 那是否SRS不超过100%使用率,就不会过载?不对,因为其他的进程可能也在消耗,不能只看SRS的CPU消耗。

因此,对于CPU来说,知道流媒体服务器能消耗多少CPU,获取流媒体服务器的CPU消耗,才能准确定义过载:

  • 系统总CPU,超过80%认为过载,比如8CPU的服务器,总CPU超过640%就认为过载,一般系统的load值也升很高,代表系统很繁忙。

  • SRS每个进程的CPU,超过80%认为过载,比如8CPU的服务器总CPU只有120%,但SRS的进程占用80%,其他占用40%,那么此时也是过载。

网络带宽,一般是根据以下几个指标判断是否过载,流媒体一般和流的码率Kbps或Mpbs有关,代表这个流每秒是多少数据传输:

  • 是否超过服务器出口带宽,比如云服务器公网出口是10Mbps,那么如果平均码率是1Mbps的直播流,超过10

你可能感兴趣的:(音视频开发,流媒体服务器,Android音视频开发,服务器,负载均衡,java,音视频,视频编解码)