一、概述

流媒体服务器(视频服务器)是在线视频应用的核心系统,用于支持海量大并发的视频播出服务,实现将视频存储、视频转码、协议复用、大并发播出等的工作集中处理,业务系统可以只关注业务细节而不用再去处理与视频相关的诸多技术细节,从而实现提高项目实施效率、降低项目实施风险的目标。
那么流媒体服务器是如何实现高负载大并发的呢,其中有几项技术细节至关重要,下面以流媒体服务器 NTV Media Server G3 所采用的技术细节为例来说明。


二、关键技术

1、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加速内核与用户空间的消息传递

2、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);

3、文件指针复用

对于视频点播应用,理想的情况是在大并发情况下很多用户在访问有限的数个热点资源,这时候优化的空间就很大。如果为每个用户请求单独打开一个文件句柄,那么就无法在进行文件指针复用,磁盘IO和内存会显著增高。如果我们只为每个相同文件打开一个句柄,多个用户请求一个文件时进行读指针复用,情况就会好的多。另外,这个打开的文件会被加载到内存里,众多的读操作只是在内存中进行,而不是进行磁盘读写,这个操作对消除磁盘IO瓶颈起到了关键作用。

三、超大并发的处理

当并发量超过1万,达到数万甚至数十万时,在单机上进行优化的手段就显得力不从心了,这时候需要从网络架构和集群的较多去考虑问题。NTV Media Server G3有两种方案处理海量并发,一是集群方案,通过多台服务器之间建立负载均衡来实现大并发;二是CDN加速方案,通过与CDN系统建立加速配置关系,将负载转移给CDN,实现全球范围的大并发播出。 当然,CDN与流媒体服务器的负载已经没有太多关系,是另外一个可以独立探讨的技术话题。

©著作权归作者所有:来自51CTO博客作者北京王老师的原创作品,如需转载,请注明出处,否则将追究法律责任

您的赞赏是最大的鼓励!

赞赏

0人进行了赞赏支持

更多相关文章

  1. Unity | 快速集成华为AGC云存储服务
  2. 笔记本剪切时中断,文件不见了怎么找回
  3. RocketMQ核心技术精讲与高并发抗压实战
  4. 运维必须掌握的Linux面试题
  5. Java并发锁(一):悲观锁与乐观锁
  6. Git原理架构详解
  7. 通过 Python 查询 Excel 数据
  8. Java并发编程高阶技术高性能并发框架源码解析与实战
  9. Linux磁盘空间释放问题

随机推荐

  1. android仿今日头条个人中心页面
  2. XML-SHAPE
  3. android 图表引擎
  4. android studio 常见问题
  5. Android系统自带的camera默认使用后置摄
  6. Ubuntu 13.04 编译环境配置及android 2.3
  7. SafetyNet & 漏洞rootutils 利用
  8. OpenGL,Android注意事项初始化顺序 NullP
  9. Android Studio 第五十三期 - 自定义Edit
  10. [android]编译时出现/usr/bin/ld: skippi