nginx-rtmp-module的缺陷分析
Arut最初在开发nginx-rtmp-module的时候只实现了单进程模式,好处是架构简单,推送和播放,数据统计,流媒体控制等都在一个进程上完成。但是这显然浪费了Nginx多进程(在Linux和FreeBSD平台上每个进程都可以绑定一个CPU核心,以减少进程切换带来的开销)的处理能力。但是,如果开启多进程模式,推送和播放如果不在同一个进程上,会造成播放失败的问题:
另外,请求数据统计信息也是个问题,因为采取HTTP方式请求数据统计信息时,在多进程模式下,请求被Nginx随机分配给了worker进程,可能造成我想看worker 1上的数据统计信息,但是Nginx返回的是worker 3上的数据统计信息。流媒体控制也采取了HTTP请求的方式,所以也存在着同样的问题:
针对推送和播放不在同一个进程上的问题,Arut后来加入了auto push的功能,即把原始的推流数据再relay到其他进程上去。这个功能需要Unix domain socket的支持(所以类Unix系统都支持,Windows在Windows 10的某个版本后才开始支持):
这样处理后,不管播放请求落在哪个进程上,都能获得推送数据。
对于后面两个问题,Arut给出了一个布丁,需要修改Nginx本身的源代码,详情见per-worker-listener。这样处理后,在HTTP请求时加上端口号信息,就可以指定请求某个进程上的数据统计信息了,流媒体控制类似:
在测试中发现auto push的并发性能并不能随着CPU个/核数的提高而提高,一般在400~500路后就无法再提升(笔记本测试)。是什么原因呢?简单分析一下:假设服务器的CPU个/核数为N(Nginx的进程数一般配置为跟CPU个/核数相等),推流路数为M,且有M>>N,例如M=1000,N为4。假设M个推流请求被平均分配到N个进程上(实际上是不会被绝对平均分配的,但是相差不会很大),那么每个进程需要处理分配给自己本身的请求数为:
Publishers(self) = M / N
另外,要保证某个播放请求不管被哪个进程接受都能成功,那么每个进程都要接受另外N-1个进程的auto push过来的流,即:
Publishers(others) = M / N x (N - 1) = M - M / N
那么每个进程需要处理的推送路数为:
Publishers(all) = Publishers(self) + Publishers(others) = M / N + M - M / N = M
即每个进程需要处理的推流数跟CPU个/核数是没有关系的,并不能用增加CPU个/核数来试图提高推流并发性能,即相当于原本能将M个推流请求“平均”分配到N个进程上的方案不但没起作用,还让每个进程都处理了全部M个推流请求。
那么怎么解决这个问题呢?答案是使用被动拉的方案替代主动推(auto push)的方案。此方案要用到共享内存和互斥锁,当一个推流请求被某个进程接受后,在共享内存中记录推送的流和某个进程的映射信息。而当一个播放请求被某个进程接受后,需要先查找要播放的流是在哪个进程上发布的,然后再到发布流的进程上去请求数据:
这样就解决了上述的每个进程都要处理全部进程接收到的推流请求的问题。
关于nginx-rtmp-module的缺陷暂时介绍到这儿,其实nginx-rtmp-module还有很多其他的缺陷,后续有时间我会写文章介绍。
欢迎关注我在nginx-rtmp-module的基础上开发的项目:nginx-http-flv-module。
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Redis 概念以及底层数据结构
Redis 简介 REmote DIctionary Server(Redis) 是一个由SalvatoreSanfilippo写的key-value存储系统。 Redis是一个开源的使用ANSI C语言编写、遵守BSD协议、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。 它通常被称为数据结构服务器,因为值(value)可以是字符串(String), 哈希(Map), 列表(list), 集合(sets) 和有序集合(sorted sets)等类型。 Redis特点 Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库。 Redis 与其他 key - value 缓存产品有以下三个特点: Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。 Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。 Redis支持数据的备份,即master-slave模式的数据备份。 Redis 优势 性能极高 – Redi...
- 下一篇
redis异地多活理论基础之CRDT
随着服务规模的扩大, 为了提升系统的容灾能力以及性能的要求, 会将服务部署在多个地域, 如果服务是有状态的, 比如redis/mysql等, 就需要在多地域之间进行数据同步, 如何保证数据一致性, 就成为了实现"多活"的关键. 以redis为例, 业内已经有redislab和阿里云实现了多活, 并且都是使用的一种叫CRDT的解决方案, 所以, 本文以CRDT的论文为基础, 介绍一下CRDT的理解, 有问题欢迎指正. CRDT: 无冲突复制数据类型 解决多主架构中, 数据复制时的最终一致性问题 使用这类数据结构, 需要满足以下三个条件(比如: INCR命令满足交换律, 结合律, 但是不满足幂等) 交换律: x⊔y=y⊔x 幂等律: x⊔x=x 结合律:(x⊔y)⊔z=x⊔(y⊔z) 分类 基于操作的(CmRT), 比如incr decr等 基于状态的(CvRT), 就是传输的是最终值, 比如restore 数据类型 Op-based counter 解释: 基于操作实现, 每个下游需要同步相同的操作, 查询时直接查询本地即可 说明: 适合类似INCR/DECR等命令, 但是需要确保幂等性...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- Red5直播服务器,属于Java语言的直播服务器
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- 设置Eclipse缩进为4个空格,增强代码规范
- CentOS8安装Docker,最新的服务器搭配容器使用
- MySQL8.0.19开启GTID主从同步CentOS8
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- CentOS7设置SWAP分区,小内存服务器的救世主