小结高并发与C10K问题


高并发与C10K问题


C10k 问题的本质:

  • 互联网的基础就是网络通信,最初的服务器都是基于进程/线程模型

  • 新到来一个TCP连接,就需要分配1个进程(或者线程)。

  • 进程又是操作系统最昂贵的资源,一台机器无法创建很多进程。

  • 如果是C10K就要创建1万个进程,那么操作系统是无法承受的。

  • 如果是采用分布式系统,维持1亿用户在线需要10万台服务器,成本巨大

解决方法:

-(1)每个进程/线程处理一个连接 资源占用过多,可扩展性差

-(2)每个进程/线程同时处理多个连接(IO多路复用)


IO多路复用:

select

同时监控多个文件句柄有连接请求抵达了再检查处理

缺点  句柄上限 

        重复初始化

       逐个排查所有文件句柄状态效率不高

poll

poll 主要解决 select 的前两个问题

  通过一个设计新的数据结构提供使用效率,消除文件句柄上限

  同时使用不同字段分别标注关注事件和发生事件来避免重复初始化

  缺点逐个排查所有文件句柄状态效率不高

epoll

只返回状态变化的文件句柄

缺点 依赖特定平台Linux
  • Epoll就成为C10K killer、高并发、高性能、异步非阻塞这些技术的代名词

  • 文件句柄数目超过 10 之后,epoll 性能将优于 select 和 poll

  • 当文件句柄数目达到 10K 的时候,epoll 已经超过 select 和 poll 两个数量级。

  • Nginx,libevent,node.js这些就是Epoll时代的产物。


协程coroutine

各个协程之间的切换,往往是用户通过代码来显式指定的(跟各种 callback 类似), 不需要内核参与,可以很方便的实现异步

协程是异步非阻塞的另外一种展现形式

生成器 yield,send 也是一种异步模型

greenlet  手动切换

gevent   自动切换但是不识别 timesleepsocket的io阻塞
          需要加上  from gevent import monkey;monkey.patch_all()放到文件的开头

注意:

  • 协程 程序级别的切换

  • epoll 是操作系统级别的切换

Buy me a 肥仔水!