UDP并发服务器设计讨论

UDP并发服务器设计讨论:一台主机、一个CPU,实现单位时间内最大并发数 楼主 HuangRG(.....) 2006-03-13 12:07:21 在 专题开发/技术/项目 / 网络通信 提问

讨论:“一台主机、一个CPU”,用UDP实现单位时间内最大并发数的接入服务器的方案。设计方案不考虑特定OS系统。 
为了简化讨论,我们简化该服务器的流程:接收UDP包---->处理数据包。流程就两步,且假设接收 
UDP包的时间Tr和处理数据包的时间Tp的关系为:Tp = K*Tr。 
设计方案一:一个线程处理整个流程。 
设计方案二:一个接收线程+一个缓冲队列+一个处理线程。 
设计方案三:N个接收线程+一个缓冲队列+一个处理线程,其中N > 1。 
设计方案四:N个接收线程+N个缓冲队列+一个处理线程,其中N,M > 1,N和M可以相等。 
为更有利于讨论,我们再假设Tp = K*Tr中的K相当大,也就说,相对Tp,Tr可忽略不计(现实应用中大部分情况也是这样的^-^)。 
在K足够大的情况下,可以肯定,方案一并发性能是最差的。 
方案二实现起来最直观,要作数据写入队列和从队列读出数据时的同步,由于我们关心的写入性能,所以不用Multi Read Single Write锁进行同步。这里在要注意的是,从队列读出数据后就要解锁。 
方案三多了一些接收线程,但所有的接收线程和处理线程在写数据到缓冲队列列时都要作同步。 
方案四是一个接收线程对应一个缓冲队列,接收线程之间不须要同步(通过TSS),但每一个接收线程还须要和处理线程同步。(有没有方法做到当两个读写线程同时访问公共资源的时候,不须要作同步?^-^)。 
我在这方面的经验不多,就两年前做过一个即时通信的接入服务器。当时做这个系统的时候,领导们催得紧,选择方案三,也经得起压力测试。 
但我现在想想,在一个CPU的情况下,方案二的性能比方案三的性能来得更高一些。方案四相对于方案二,可能可以支持更多的并发数,但性能会下降。为什么会得出这样的结论呢?因为方案四中的接收线程间不须要同步!可以肯定的是在多CPU的情况下,方案四是首选。 
我现在不从事这方面的工作了,没有那么多机器做测试,所以没有办法做这几个方案的比较测试,得出实验结果。希望兄弟们说出自己的观点;有条件的请给出测试数据。 


问题点数:20、回复次数:15Top

1 楼faxiao(faxiao)  回复于 2006-03-16 14:57:00 得分 0

为啥不用多个处理线程?接收线程应该问题不大,主要是处理跟缓冲的冲突,处理得快,缓冲多了也没用,处理的慢,缓冲还是不够用,影响接收的写入。应该做到处理跟写入速度平衡就差不多了,缓冲可能不需要很大Top

2 楼ugvihc(maybe good good study, hope day day up!)  回复于 2006-03-17 10:22:46 得分 0

最近也在做一个同样的的事情,考虑的和楼上的差不多, 
希望利用多线程, 
一个缓冲队列+多个处理线程. 
一个检查缓冲队列的线程,若检查到缓冲队列非空,则将数据扔给某一空闲处理线程进行处理. 
但具体还没有想好,那里有类似的设计,请高手指教:)Top

3 楼mme(dog)  回复于 2006-03-19 14:19:40 得分 0

一个收包线程,一个缓冲队列,多个处理线程,我认为在1个cpu上是最好的了。Top

4 楼gohappy_1999(碧水蓝天)  回复于 2006-03-24 09:03:20 得分 0

gzTop

5 楼ugvihc(maybe good good study, hope day day up!)  回复于 2006-04-11 17:41:32 得分 0

感觉N个接收线程,一个缓冲队列,M个处理线程性能比较好.Top

6 楼tom_tom(男的想通了,女的想开了,两人就结婚了!)  回复于 2006-04-12 17:06:12 得分 0

g zTop

7 楼yevon(匪匪斗神)  回复于 2006-04-29 16:37:26 得分 0

GZTop

8 楼ensoniq()  回复于 2006-04-29 17:38:38 得分 0

IMHO,貌似LZ没有认识到问题真正在哪里。1个CPU处理Task,如果处理的过程中不会发生I/O阻塞,你用多线程干吗?Task A in Thread A, Task B in Thread B,无论是并发还是依次,处理的总共时间必定是相等的。 

多线程能对你的性能做贡献的场合,要么是你有多个CPU,多个线程可以真实地并行运行,要么是你的线程里有I/O阻塞的操作,这时候用多个线程可以重叠掉I/O阻塞浪费掉的时间。但即使你使用多线程来防止I/O阻塞,也不可能有直接对I/O进行计划处理来得高效,因为多线程的唤醒选择具有随机性,并且多线程本身必定有系统开销。Top

9 楼ensoniq()  回复于 2006-04-29 17:42:32 得分 0

一般的socket操作和文件读写全是I/O阻塞的。其实IOCP就是直接对I/O进行挂接处理的解决方案。UNIX上的解决方案我不熟悉。不明白这个怎么能做到OS无关呢。Top

10 楼mynamelj(风动,帆动,仁者心动)  回复于 2006-05-03 11:02:34 得分 0

在单CPU上使用多线程意义不大,我觉接数线程一个就够了,关键是处理线程(结合数据库). 

不信你可以测试一下,客户端不断的发送数据包(不要全速),服务端不断的接收.如果你的内存增长得比较快的话那就证明你的处理线程是供不应求.Top

11 楼netfairy(泡泡猪)  回复于 2006-05-03 21:50:26 得分 0

楼上很多人都说了,在单CPU上,多线程的效率绝对小于单线程的。其实单线程的程序就是自己做调度,而自己做调度的效率肯定比线程的通用调度模型来得高效。如果不要求一个比较通用的网络层的话,全部一个线程也能搞定啊,而且绝对是效率最高的做法。当然,多CPU不在考虑之列。 
其实这种问题的设计,主要在于资源瓶颈的分析:估算一下单个用户的带宽、cpu、内存等消耗量,如果还有后台数据库,那么后台数据库的处理能力一般就是瓶颈了,考虑用内存之类的换点。除了瓶颈,其他东西都是次要的,这是服务器架构设计的关键。Top

12 楼netfairy(泡泡猪)  回复于 2006-05-03 21:52:45 得分 0

处理线程如果有IO操作,或者其他空转的CPU周期,那么多个处理线程是必要的。当然,如果处理程序比较简单,不是瓶颈,随便写也无所谓。Top

13 楼onlyxuyang()  回复于 2006-05-04 14:42:14 得分 0

ACETop

14 楼gengyong(gengyong)  回复于 2006-07-05 19:00:39 得分 0

最可能成为最优的方案被你第一个否定了。 
如果你的处理流程是计算密集操作,而非IO密集操作,第一个方案可能是最优选择。 

如果处理流程有很多IO, 使用线程以避免IO时CPU资源耗费,可能是最优选择。 
假定使用多线程方案,3个多线程方案中,方案2可能在单CPU系统中表现会较佳(考虑线程切换的代价, 多线程竞争的代价--毕竟,物理上的IO只有一个,另外,google一下“惊群”可知另一些信息)。方案4在SMP系统中可能表现会较佳(相对方案3, 可以减少很多同步操作,产生性能颠簸的几率也相对小一些)。 

以上只是泛泛的理论分析, 根据实际应用的不同, 可能会有不同的结果。 
Top

15 楼WinEggDrop(WinEggDrop)  回复于 2006-07-07 03:10:59 得分 0

如果接收UDP包和处理数据两部分都是阻塞的话,那么方案三和四是肯定需要的. 
但如果两部分都可以使用异步方式处理,那么就要在实际环境中测试过才知道.接收UDP数据方面我是做过,对于N个客户连接,使用异步(单线程接收所有数据)还是使用N个线程处理接收数据,基本上没有太大差别,差别应该只是使用的资源,使用N个线程(N > 1)使用的系统资源(主要是虚拟内存要使用得比较多或者还会使用多点CPU,如果没使用到线程池的话,线程间的切换会多用些CPU时间), 

那么剩下的就是处理数据方面了.这方面最好就是测试下,如果处理数据是写入文件的话,可以使用WriteFile()中的异步处理和多个线程阻塞处理比较下效率.Top

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值