写点什么

一种提升流媒体服务 DSS 的 IO 并发性能方案

用户头像
Changing Lin
关注
发布于: 4 小时前
一种提升流媒体服务DSS的IO并发性能方案

1.项目概要:

本文主要介绍一种提升流媒体服务DSS的IO并发性能方案。
复制代码

2.背景和需求

在上一篇文章中,介绍了如何使用DSS作为流媒体服务,实现下游支持多路接入市面上的传统IPC,上游为用户提供远程观看、实时监控的功能。在项目落地的过程中,DSS进程工作稳定,可满足最初的设计目标,同时,验证了我们的方案的可行性。随着公司的项目应用场景的拓展,需要DSS服务支持多路的视频流同时工作和转发。比如:在轨道交通系统中,每条路线会有多趟列车,每趟列车车厢有64个摄像头。因此,对系统的并发性能提出了新的要求。通过阅读分析DSS源码,我们发现DSS中使用的IO多路复用模型是select。
复制代码

2.1 需求分析

  • 学习了解 IO 多路复用定义

  • 学习了解 Linux 平台的 select 模型的优缺点

  • 学习了解 Linux 平台的其他 IO 多路复用模型的优缺点

  • 对比各个 IO 多路复用模型的优缺点,评估升级成本与工作量

2.2 方案评估


  • 如上图所示,决定在 DSS 基础上面升级 epoll 模型,提升系统在高并发场景下的 IO 性能。

3.实现原理

3.1 新增 epollEvent.h

#ifndef _EPOLLEVENT_H__#define _EPOLLEVENT_H__
#if defined(__linux__)#include <stdio.h>#include <unistd.h>#include <sys/epoll.h>#include <stdlib.h>#include <string.h>#include "common.h"
int epollInit();
int addEpollEvent(struct eventreq *req,int event);//event {EV_RD,EV_RM}
int deleteEpollEvent(int& fd);
int epollwaitevent();
int epoll_waitevent(struct eventreq *req, void* onlyForMOSX);//stay the same with old event
int epollDestory();#endif#endif
复制代码

3.2 新增 epollEvent.cpp

未完待续
复制代码

3.3 修改 EventContext.h

diff --git a/CommonUtilitiesLib/EventContext.h b/CommonUtilitiesLib/EventContext.hindex 6fa8b83..afd3b7e 100644--- a/CommonUtilitiesLib/EventContext.h+++ b/CommonUtilitiesLib/EventContext.h@@ -48,7 +48,11 @@         #include "ev.h"     #endif #else-    #include "ev.h"+    #if defined(_ENABLE_EPOLL_EVENT_)+        #include "epollEvent.h"+    #else+        #include "ev.h"+    #endif //_ENABLE_EPOLL_EVENT_ #endif
复制代码

3.4 修改 EventContext.cpp

diff --git a/CommonUtilitiesLib/EventContext.cpp b/CommonUtilitiesLib/EventContext.cppindex 7cec317..306f697 100644--- a/CommonUtilitiesLib/EventContext.cpp+++ b/CommonUtilitiesLib/EventContext.cpp@@ -94,7 +94,11 @@ void EventContext::Cleanup()             fEventThread->fRefTable.UnRegister(&fRef);  #if !MACOSXEVENTQUEUE+        #if defined(_ENABLE_EPOLL_EVENT_)+            deleteEpollEvent(fFileDesc);+        #else             select_removeevent(fFileDesc);//The eventqueue / select shim requires this+        #endif //_ENABLE_EPOLL_EVENT_ #ifdef __Win32__             err = ::closesocket(fFileDesc); #endif@@ -162,14 +166,18 @@ void EventContext::RequestEvent(int theMask)     // The first time this function gets called, we're supposed to     // call watchevent. Each subsequent time, call modwatch. That's     // the way the MacOS X event queue works.-    +     if (fWatchEventCalled)     {         fEventReq.er_eventbits = theMask; #if MACOSXEVENTQUEUE         if (modwatch(&fEventReq, theMask) != 0) #else+    #if defined(_ENABLE_EPOLL_EVENT_)+        if (addEpollEvent(&fEventReq, theMask) != 0)+    #else         if (select_modwatch(&fEventReq, theMask) != 0)+    #endif //_ENABLE_EPOLL_EVENT_ #endif               AssertV(false, OSThread::GetErrno());     }@@ -208,7 +216,11 @@ void EventContext::RequestEvent(int theMask) #if MACOSXEVENTQUEUE         if (watchevent(&fEventReq, theMask) != 0) #else+    #if defined(_ENABLE_EPOLL_EVENT_)+        if (addEpollEvent(&fEventReq, theMask) != 0)+    #else         if (select_watchevent(&fEventReq, theMask) != 0)+    #endif //_ENABLE_EPOLL_EVENT_ #endif               //this should never fail, but if it does, cleanup.             AssertV(false, OSThread::GetErrno());@@ -229,7 +241,11 @@ void EventThread::Entry() #if MACOSXEVENTQUEUE             int theReturnValue = waitevent(&theCurrentEvent, NULL); #else+        #if defined(_ENABLE_EPOLL_EVENT_)+            int theReturnValue = epoll_waitevent(&theCurrentEvent, NULL);+        #else             int theReturnValue = select_waitevent(&theCurrentEvent, NULL);+        #endif //_ENABLE_EPOLL_EVENT_ #endif               //Sort of a hack. In the POSIX version of the server, waitevent can return             //an actual POSIX errorcode.
复制代码

4.使用方法

./Buildit    // 编译dss可执行文件./Buildit clean    // 删除编译生成的.o文件./clean    // 清除所有编译的文件,包括可执行文件、压缩包等
复制代码

5.对比

经过一段时间的测试,对比发现epoll模型,在多路高并发场景下,启动播放首帧时延较低,用户体验更好。如同时转发128路1080P的高清码流。
复制代码

6.总结

由于DSS代码的可扩展性和模块化,帮助我们再升级IO多路复用模型时,提供了稳定的平台支持。在开发过程中,不仅减少了开发工作量,同时又具备独立单元测试的条件,有助于开发更稳定的软件。
复制代码

7.参考文献

https://www.cnblogs.com/aspirant/p/9166944.htmlhttps://jvns.ca/blog/2017/06/03/async-io-on-linux--select--poll--and-epoll/https://devarea.com/linux-io-multiplexing-select-vs-poll-vs-epoll/#.YHzyFJ_iuUkhttps://xie.infoq.cn/article/a7ffc059fd627acc52d0ca231
复制代码


发布于: 4 小时前阅读数: 2
用户头像

Changing Lin

关注

获得机遇的手段远超于固有常规之上~ 2020.04.29 加入

我能做的,就是调整好自己的精神状态,以最佳的面貌去面对那些未曾经历过得事情,对生活充满热情和希望。

评论

发布
暂无评论
一种提升流媒体服务DSS的IO并发性能方案