发文章
发文工具
撰写
网文摘手
文档
视频
思维导图
随笔
相册
原创同步助手
其他工具
图片转文字
文件清理
AI助手
留言交流
在我们实现的分布式服务器中,每个节点都存有时空数据,这些节点上的时空数据利用RTree进行索引。每个节点同时保存着路由(邻居节点)信息。客户端可以向服务器端发送数据查询请求。服务器负责接收请求,并根据请求的类型进行相应的处理, 包括查询本地的数据,转发请求到邻居节点。
时空数据是以数据流的形式源源不断的插入到服务器中。当某个节点的数据达到系统预定义的阈值时,该节点将分裂成两个节点。我们将计算数据的最优划分策略划分数据,并将划分的数据迁移到新的节点上。同时更新当前节点和新建节点的路由信息。
针对上面的要求,我们的服务器需要满足以下两个目标:
服务器中同时存在两种连接方式:长连接和短连接。长连接是指Client端与Server端先建立通讯连接,连接建立以后不断开,然后再进行报文的发送和接收。长连接常用于点对点的通讯,在服务器中,数据传输采用长连接。短连接是指Client端和Server端只有在进行一次报文收发操作时才进行通讯连接,操作完毕以后立即关闭连接。短连接一般针对一点对多点的通讯,如多个Client连接一个Server。在服务器中,数据查询请求采用短连接。
常见的网络服务器采用以下几种方式:
第1种方式缺点在于当并发连接数过高时,操作系统同时处理几百个线程会有性能问题。而且在服务器硬件配置不改变的情况下,随着连接数的增加,将会导致性能急剧下降。第3种方式目前在Unix上还没有普遍的应用,因此,在我们的系统中并没有采用。第2种方式是将网络句柄设置为非阻塞模式,然后使用select或者poll IO多路复用技术来告知那个句柄已经有数据在等待处理。在此模型下,由系统内核来告知应用程序某个网络句柄的状态。这种模型也就是传统的IO多路复用模型,是目前大部分网络服务器的解决方案。
我们的服务器是基于Linux开发的,在Linux上,实现IO多路复用有几个主要的技术,分别是select模型,poll模型和epoll模型。
select模型最大的缺点是最大并发数限制,因为一个进程所打开的socket FD(文件描述符)是有限制的,默认是1024,因此select模型的最大并发数就被限制了。当然,我们可以通过修改系统参数增大最大并发数,然而由于select的每次调用都会线性扫描全部的socket FD集合。当socket FD增大时,会导致服务器效率线性下降。
poll模型基本上和select在效率上是一样的,select的问题在poll模型中也没有被解决。
epoll模型是目前比较优秀的IO多路复用模型,首先,epoll没有最大并发连接的限制,上限是整个系统最大可以打开的socket FD数目,这个数远大于2048,一般这个数目和系统内存关系很大,1G内存的机器的最大sockef FD数目可以达到10万左右。其次,epoll最大的优点在于它只关心活跃的连接,而跟连接总数无关。因此在实际的网络环境中,epoll的效率会远高于select和poll。
鉴于epoll的优点,我们的服务器采用了epoll作为IO多路复用的基本技术。
常见的基于epoll的设计模式主要为单线程的事件循环,用于一些非阻塞的业务逻辑开发是很高效的,然而,在我们的服务器开发中,涉及传输数据。转发请求的需求,耗时比较长。因此,单线程的epoll并不能满足我们的需要。下面用一个简单的例子来说明单线程模式下epoll的缺点。
由于是单线程模型,当某个客户端的请求处理时间较长时,会影响服务器接收来自其他客户端的连接请求,进而影响整个服务器的并发性能。
因此,单线程的epoll模型在我们的分布式服务器中并不适用。下面是我们服务器的设计方案:
图2 图3
上面这种设计模式一般称为Reactor模式,Reactor模式是处理并发I/O比较常见的一种模式,中心思想是首先将所有要处理的I/O事件添加到一个中心的多路复用器上(epoll), 同时主线程阻塞在多路复用器上;一旦有连接到来或者是准备就绪,多路复用器将返回并将相应的I/O事件分发到对应的处理线程中。
我们的服务器采用了多个Reactor,也就是多线程的epoll。 Reactor被分为main reactor和sub reactors,分别对应图2 和图3。每个reactor中都有独立的epoll来作为多路复用器。其中main reactor中的epoll负责监听连接请求,一旦有连接到来,利用一定的分发策略将连接socket加入到sub reactors的epoll中。对于每个sub reactor的epoll,主要的工作就是监听连接socket,一旦某个连接socket的I/O准备就绪,则通知相应的handler来接收数据并处理请求。
通过使用非阻塞I/O的多路复用技术epoll,并将连接请求与连接建立的之后的逻辑分离,我们设计了基于Reactor设计模式的服务器,满足了高并发的处理数据查询请求与数据传输请求。并能够同时处理长连接与短连接。 同时,还有一些细节我们可以改进:
目前我们采用了Round-robin的方式,这样有可能产生负载不均衡的现象。 后面我们可以使用一定的策略,将main reactor接收到的连接请求分发到相对空闲的sub
reactor中。保证整个系统的负载均衡。
对于每个sub reactor来说,这是单线程的。 我们同样可以将sub reactor进一步划分, 将数据的接收与请求的处理分离,请求的处理采用线程池的方式。这将进一步提高服务 器的并发能力。
特此感谢ChinaUnix论坛的@linux_c_py_php的一篇帖子给我带来的巨大帮助,友情链接:http://bbs./thread-4067753-1-1.html
转载请注明出处: http://www.cnblogs.com/meibenjin/p/3604389.html
来自: 昵称10504424 > 《工作》
0条评论
发表
请遵守用户 评论公约
网络编程模型综述 之 成熟的IO框架介绍
网络编程模型综述 之 成熟的IO框架介绍ACE。“重量级的C I/O框架,用面向对象实现了一些I/O策略和其它有用的东西,特别是它的Reactor是...
Netty框架整体架构及源码知识点
Netty框架整体架构及源码知识点Netty概述。1)NioEventLoop实际上就是工作线程,可以直接理解为一个线程。Netty通过Reactor模型基于多路复用器接收并处理用户请求,内部实现了两个线程池,boss线程池和...
Linux高性能服务器程序框架
Reactor模式:同步IO模型(以epoll_wait为例)实现的Reactor模式的工作流程:1、主线程往epoll内核事件表中注册socket上的读就绪事件。...
如何设计真正高性能高并发分布式系统(万字长文)
申请线程或进程会占用很多系统资源,操作系统cpu、内存有限度,能同时管理的线程有限,处理连接的线程不能太多。业务线程池线程池分配独...
IO回忆录之怎样过目不忘(BIO/NIO/AIO/Netty)2017版
IO回忆录之怎样过目不忘(BIO/NIO/AIO/Netty)2017版。有人问:单看实现原理,显然AIO要比NIO高级,为什么Netty底层用NIO? Netty也曾经做过一些AIO的尝试性版本,但是性能效果不理想。Netty可以定制,可...
利用C语言实现http服务器
最后通过独立完成一个基于Linux平台C语言编写的http服务器,巩固课程学到的Linux平台上的编程规范、技术和技巧,增强对于Linux操作系统的熟练度,培养我们编写较大型程序的能力,培养底层软件开发的能...
IO多路复用、非阻塞式IO
IO多路复用、非阻塞式IO.现实生活中的例子,餐厅,阻塞IO类似于每来一个客人我马上分配一个厨师,让厨师等着客人点餐,然后再去做饭,厨...
UDP笔记 第四部分 续和转载(2)—— UNIX 网络高级I/O模型
UDP笔记 第四部分 续和转载(2)—— UNIX 网络高级I/O模型UDP笔记 第四部分 续和转载(2)—— UNIX 网络高级I/O模型2009-03-31 10:01.IO...
浅谈服务器单I/O线程+工作者线程池模型架构及实现要点
浅谈服务器单I/O线程+工作者线程池模型架构及实现要点。我们知道,服务器并发模型通常可分为单线程和多线程模型,这里的线程通常是指“...
微信扫码,在手机上查看选中内容