C10k-problem

来源:互联网 发布:淘宝怎么设置上新提醒 编辑:程序博客网 时间:2024/06/06 05:46
知识预热

线程:
      一般是一个CPU核心对应一个线程的,核心越多,线程越多,处理能力越出色。而因特尔I系列的CPU可以模拟多线程技术,达到更高的处理运算能力,但是因为是模拟的,所以并不能与实际核心相提并论。例如INTEL的I3就是双核4线程。(当然,编程的时候要注意的是,CPU 0 不能用得过狠)

 I/O :
     任何瞬间也只能有一个磁头在工作,其他磁头闲置。 由于 VM,cache , 有各种东东的存在,一次I/O不代表一次读写。

     I/O Stack的流程(内核3.3版本的I/O Stack):
         I/O Stack流图分为几大部分:
            1>.direct I/O 的O_Direct调用
            2>.Page Cache;
            3>.VFS,也即文件系统、网络通信等
            4>.Block I/O层
            5>.I/O调度方式;
            6>.SCSI处理层;
            7>.磁盘硬件设备;   

(来自thomas-krenn.com的图片) 


TCP/UDP:
     TCP是面向流的, 不会间断. TCP为了提高传输效率, 发送数据的时候, 并不是直接发送数据到网路, 而是先暂存到系统缓冲, 超过时间或者缓冲满了, 才把缓冲区的内容发送出去, 这样, 就可以有效提高发送效率. 所以会造成所谓的粘包, 即前一份Send的数据跟后一份Send的数据可能会暂存到缓冲当中, 然后一起发送.
     UDP就不同了, 面向报文形式, 系统是不会缓冲的, 也不会做优化的, Send的时候, 就会直接Send到网络上, 对方收不收到也不管, 所以这块数据总是能够能一包一包的形式接收到, 而不会出现前一个包跟后一个包都写到缓冲然后一起Send.
     
文件FD设置:
      linux对每个进程能打开的文件数目有限制。服务器需要修改破解限制。

------------------------------------------我是分割线----------------------------------------------------------

C10K
     附一篇好文章 link : http://www.kegel.com/c10k.html
     网络服务在处理数以万计的客户端连接时,往往出现效率低下甚至完全瘫痪,这被称为 C10K问题。

      C10K问题的最大特点是:设计不够良好的程序,其性能和连接数及机器性能的关系往往 是非线性的。举个例子:如果没有考虑过C10K问题,一个经典的基于select的程序能在 旧服务器上很好处理1000并发的吞吐量,它在2倍性能新服务器上往往处理不了并发2000的吞吐量。 这是因为在策略不当时,大量操作的消耗和当前连接数n成线性相关。会导致单个任务的资源消耗和当前连接数的关系会是O(n)。而服务程序需要同时对数以万计的socket进 行I/O处理,积累下来的资源消耗会相当可观,这显然会导致系统吞吐量不能和机器性 能匹配。为解决这个问题,必须改变对连接提供服务的策略。
     主要有两方面的策略:
          1.应用软件以何种方式和操作系统合作,获取I/O事件并调度多 个socket上的I/O操作;
          2. 应用软件以何种方式处理任务和线程/进程的关系。前者主 要有阻塞I/O、非阻塞I/O、异步I/O这3种方案,后者主要有每任务1进程、每任务1线 程、单线程、多任务共享线程池以及一些更复杂的变种方案。
     常用的经典策略如下:
         1.  Serve one client with each thread/process, and use blocking I/O 。Apache、ftpd等都是这种工作模式。
         2. Serve many clients with single thread, and use nonblocking I/O and readiness notification 。优点在于实现较简单,方便移植,也 能提供足够的性能;缺点在于无法充分利用多CPU的机器。尤其是程序本身没有复杂的 业务逻辑时。
         3. Serve many clients with each thread, and use nonblocking I/O and readiness notification 对经典模型2的简单改进,缺点是容易在多线程并发上出bug,甚至某些OS不支持多线程 操作readiness notification。
         4.  Serve many clients with each thread, and use asynchronous I/O 在有AI/O支持的OS上,能提供相当高的性能。不过AI/O编程模型和经典模型差别相当 大,基本上很难写出一个框架同时支持AI/O和经典模型,降低了程序的可移植性。

         在参考了一些开源的代码,和结合一些测试。我写了一个简单的socket-server以实现 C10K。
     (在我的渣本机本上,跑起来的性能远超C10K。但是,我的库没有写到业务上去,所以性能可能测出来好很多。实际要看业务来讨论真实性能)
         源码地址:https://github.com/PhoneLi/chatroom
      




6 0