zoukankan      html  css  js  c++  java
  • C10K与C10M的问题

    C10K问题本质上是操作系统的问题。对于Web1.0/2.0时代的操作系统而言, 传统的同步阻塞I/O模型都是一样的,处理的方式都是requests per second,并发10K和100的区别关键在于CPU。
    
    创建的进程线程多了,数据拷贝频繁(缓存I/O、内核将数据拷贝到用户进程空间、阻塞), 进程/线程上下文切换消耗大, 导致操作系统崩溃,这就是C10K问题的本质!

    解决方案:

    1思路一:每个进程/线程处理一个连接
    
    这一思路最为直接。但是由于申请进程/线程会占用相当可观的系统资源,同时对于多进程/线程的管理会对系统造成压力,因此这种方案不具备良好的可扩展性。
    
    因此,这一思路在服务器资源还没有富裕到足够程度的时候,是不可行的。即便资源足够富裕,效率也不够高。总之,此思路技术实现会使得资源占用过多,可扩展性差。
    2思路二:每个进程/线程同时处理多个连接(IO多路复用)
    
    IO多路复用从技术实现上又分很多种,我们逐一来看看下述各种实现方式的优劣。
    
    ● 实现方式1:传统思路最简单的方法是循环挨个处理各个连接,每个连接对应一个 socket,当所有 socket 都有数据的时候,这种方法是可行的。
    但是当应用读取某个 socket 的文件数据不 ready 的时候,整个应用会阻塞在这里等待该文件句柄,即使别的文件句柄 ready,也无法往下处理。 ● 实现方式2:select要解决上面阻塞的问题,思路很简单,如果我在读取文件句柄之前,先查下它的状态,ready 了就进行处理,不 ready 就不进行处理,
    这不就解决了这个问题了嘛?于是有了
    select 方案。用一个 fd_set 结构体来告诉内核同时监控多个文件句柄,当其中有文件句柄的状态发生指定变化
    (例如某句柄由不可用变为可用)或超时,则调用返回。之后应用可以使用 FD_ISSET 来逐个查看是哪个文件句柄的状态发生了变化。这样做,
    小规模的连接问题不大,但当连接数很多(文件句柄个数很多)的时候,逐个检查状态就很慢了。 ● 实现方式3:poll 主要解决
    select 的前两个问题:通过一个 pollfd 数组向内核传递需要关注的事件消除文件句柄上限,同时使用不同字段分别标注关注事件和发生事件,
    来避免重复初始化。 ● 实现方式4:epoll既然逐个排查所有文件句柄状态效率不高,很自然的,如果调用返回的时候只给应用提供发生了状态变化(很可能是数据 ready)的文件句柄,
    进行排查的效率不就高多了么。epoll 采用了这种设计,适用于大规模的应用场景。实验表明,当文件句柄数目超过
    10 之后,epoll 性能将优于 select 和 poll;
    当文件句柄数目达到 10K 的时候,epoll 已经超过 select 和 poll 两个数量级。 ● 实现方式5:由于epoll, kqueue, IOCP每个接口都有自己的特点,程序移植非常困难,于是需要对这些接口进行封装,以让它们易于使用和移植,
    其中libevent库就是其中之一。跨平台,封装底层平台的调用,提供统一的 API,但底层在不同平台上自动选择合适的调用。
    实现C10M意味着什么?
    
    实现10M(即1千万)的并发连接挑战意味着什么:
    
    1千万的并发连接数;
    100万个连接/秒:每个连接以这个速率持续约10秒;
    10GB/秒的连接:快速连接到互联网;
    1千万个数据包/秒:据估计目前的服务器每秒处理50K数据包,以后会更多;
    10微秒的延迟:可扩展服务器也许可以处理这个规模(但延迟可能会飙升);
    10微秒的抖动:限制最大延迟;
    并发10核技术:软件应支持更多核的服务器(通常情况下,软件能轻松扩展到四核,服务器可以扩展到更多核,因此需要重写软件,以支持更多核的服务器)。
    解决C10M问题的思路总结
    
    网卡问题:通过内核工作效率不高
    解决方案:使用自己的驱动程序并管理它们,使适配器远离操作系统。
    
    CPU问题:使用传统的内核方法来协调你的应用程序是行不通的。
    解决方案:Linux管理前两个CPU,你的应用程序管理其余的CPU,中断只发生在你允许的CPU上。
    
    内存问题:内存需要特别关注,以求高效。
    解决方案:在系统启动时就分配大部分内存给你管理的大内存页。
    好好学习,天天向上
  • 相关阅读:
    第十一章、集合
    第十章、正则表达式
    第九章、常用类
    第八章、面向对象高阶
    第七章、面向对象初识
    第六章、数组
    第五章、循环结构
    第四章、分支结构
    第三章、Java变量与数据类型
    Linux安装MySQL5.7(CentOS)
  • 原文地址:https://www.cnblogs.com/topass123/p/13571956.html
Copyright © 2011-2022 走看看