图像检索服务器编写问题记录——关于任务队列的思考

任务队列底层容器的选择:(循环数组较合适本服务器?)

         现在使用的是包装stl::queue后的自定义struct。std::queue可以使用deque(双端队列)作为底层容器(queue q);也可以使用list作为底层容器(queue > q)。

         若底层容器使用list,每个节点除任务信息外,均含一个指向下个节点的next指针索引。虽然相对于以deque为底层容器的队列,更能利用分散的内存,但是附加索引耗的内存比较大。而若底层容器使用deque,如下:

                    图像检索服务器编写问题记录——关于任务队列的思考_第1张图片

      考虑到图像检索服务,一个检索任务耗时较长,且本实验环境cpu12核,除开其他长活线程,计算任务线程同时进行的最多8~9个,所以其实任务队列中存放的任务太多会导致任务堆积问题,很多任务长时间得不到处理,响应时间太长(解决方法,其他一个话题),所以为防止任务响应时间太长,任务队列中的任务个数不应该太大,比如按本实验环境,13个?这种小任务队列,使用deque有些不值当(随着pop,push进行,第一块和最后一块小内存块必然会空出很多)。所以我认为底层容器使用循环数组就可以满足需求了。


任务队列太大导致任务响应时间太长;任务队列太小导致任务无法接收?

     如上描述,一个检索任务的耗时比较长,且主要耗在特征向量的计算和特征库相似度计算上,cpu12核,除开其他线程,最多有8~9线程处理计算任务,也就是说,为了让任务得到即使处理,并处理完,那么任务个数短板差不多就是10左右。所以为了使客户端等太久,任务队列不能太大,一大就会出现后来的用户请求迟迟得不到响应。

     那么任务队列太小怎么办?任务队列太小,当任务队列满的时候就拒绝接收客户端的请求么?还是用操作系统那样的时间片轮转(任务还是接,但是每个任务均有处理时间片,时间片到了任务还没处理完,那么就记录此时任务状态,再将任务挂到任务队列的尾端去)?

     一直拒绝客户端请求,和接收请求但任务长期得不到处理是一个用户体验(一个效果:等)。时间片轮转和 [ 忽视cpu核数,滥开线程个数 ]是一个效果,频繁切换(少了系统线程切换的上下文保存,多了应用层任务切换的上下文保存),大家一起等任务执行完。

     最后想来想去,只能添加服务器。后台处理检索任务的服务器集群+接收并发请求的代理服务器。

     编写代理服务器承受并发的检索请求,并将检索请求按 [ 检索服务器负载情况 ] 分发给 [ 后台的处理检索任务的服务器 ]。  后台检索服务器使用循环队列接收任务,可以衡量队列的饱和度,代理服务器跟据各检索服务器队列饱和度来分发检索任务。

      啊,妈呀,这么一想工作量好大。

    


你可能感兴趣的:(图像检索服务器编写记录)