C10K 问题

服务器应用领域很古老很出名的一个问题,大意是说单台服务器要同时支持并发 10K 量级的连接,这些连接可能是保持存活状态的。

解决这一问题,主要思路有两个:一个是对于每个连接处理分配一个独立的进程/线程;另一个思路是用同一进程/线程来同时处理若干连接。

每个进程/线程处理一个连接

这一思路最为直接。但是由于申请进程/线程会占用相当可观的系统资源,同时对于多进程/线程的管理会对系统造成压力,因此这种方案不具备良好的可扩展性。

因此,这一思路在服务器资源还没有富裕到足够程度的时候,是不可行的;即便资源足够富裕,效率也不够高。

问题:资源占用过多,可扩展性差。

每个进程/线程同时处理多个连接

传统思路

最简单的方法是循环挨个处理各个连接,每个连接对应一个 socket,当所有 socket 都有数据的时候,这种方法是可行的。

但是当应用读取某个 socket 的文件数据不 ready 的时候,整个应用会阻塞在这里等待该文件句柄,即使别的文件句柄 ready,也无法往下处理。

  • 思路:直接循环处理多个连接。
  • 问题:任一文件句柄的不成功会阻塞住整个应用。

select

要解决上面阻塞的问题,思路很简单,如果我在读取文件句柄之前,先查下它的状态,ready 了就进行处理,不 ready 就不进行处理,这不就解决了这个问题了嘛?

于是有了 select 方案。用一个 fd_set 结构体来告诉内核同时监控多个文件句柄,当其中有文件句柄的状态发生指定变化(例如某句柄由不可用变为可用)或超时,则调用返回。之后应用可以使用 FD_ISSET 来逐个查看是哪个文件句柄的状态发生了变化。

这样做,小规模的连接问题不大,但当连接数很多(文件句柄个数很多)的时候,逐个检查状态就很慢了。因此,select 往往存在管理的句柄上限(FD_SETSIZE)。同时,在使用上,因为只有一个字段记录关注和发生事件,每次调用之前要重新初始化 fd_set 结构体。

int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
  • 思路:有连接请求抵达了再检查处理。
  • 问题:句柄上限+重复初始化+逐个排查所有文件句柄状态效率不高。

poll

poll 主要解决 select 的前两个问题:通过一个 pollfd 数组向内核传递需要关注的事件消除文件句柄上限,同时使用不同字段分别标注关注事件和发生事件,来避免重复初始化。

int poll(struct pollfd *fds, nfds_t nfds, int timeout);
  • 思路:设计新的数据结构提供使用效率。
  • 问题:逐个排查所有文件句柄状态效率不高。

epoll

既然逐个排查所有文件句柄状态效率不高,很自然的,如果调用返回的时候只给应用提供发生了状态变化(很可能是数据 ready)的文件句柄,进行排查的效率不就高多了么。

epoll 采用了这种设计,适用于大规模的应用场景。

实验表明,当文件句柄数目超过 10 之后,epoll 性能将优于 select 和 poll;当文件句柄数目达到 10K 的时候,epoll 已经超过 select 和 poll 两个数量级。

int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);
  • 思路:只返回状态变化的文件句柄。
  • 问题:依赖特定平台(Linux)。

libevent

跨平台,封装底层平台的调用,提供统一的 API,但底层在不同平台上自动选择合适的调用。

C10K 到 C10M

随着技术的演进,epoll 已经可以较好的处理 C10K 问题,但是如果要进一步的扩展,例如支持 10M 规模的并发连接,原有的技术就无能为力了。

那么,新的瓶颈在哪里呢?

从前面的演化过程中,我们可以看到,根本的思路是要高效的去阻塞,让 CPU 可以干核心的任务。

当连接很多时,首先需要大量的进程/线程来做事。同时系统中的应用进程/线程们可能大量的都处于 ready 状态,需要系统去不断的进行快速切换,而我们知道系统上下文的切换是有代价的。虽然现在 Linux 系统的调度算法已经设计的很高效了,但对于 10M 这样大规模的场景仍然力有不足。

所以我们面临的瓶颈有两个,一个是进程/线程作为处理单元还是太厚重了;另一个是系统调度的代价太高了。

很自然地,我们会想到,如果有一种更轻量级的进程/线程作为处理单元,而且它们的调度可以做到很快(最好不需要锁),那就完美了。

这样的技术现在在某些语言中已经有了一些实现,它们就是 coroutine(协程),或协作式例程。具体的,Python、Lua 语言中的 coroutine(协程)模型,Go 语言中的 goroutine(Go 程)模型,都是类似的一个概念。实际上,多种语言(甚至 C 语言)都可以实现类似的模型。

它们在实现上都是试图用一组少量的线程来实现多个任务,一旦某个任务阻塞,则可能用同一线程继续运行其他任务,避免大量上下文的切换。每个协程所独占的系统资源往往只有栈部分。而且,各个协程之间的切换,往往是用户通过代码来显式指定的(跟各种 callback 类似),不需要内核参与,可以很方便的实现异步。

参考文献

  • http://www.ulduzsoft.com/2014/01/select-poll-epoll-practical-difference-for-system-architects/
转载请注明:http://blog.csdn.net/yeasy/article/details/43152115

C10K 问题引发的技术变革相关推荐

  1. 【技术趋势】德勤发布2020技术趋势报告,五个新趋势可引发颠覆性变革

    来源:产业智能官 "2020 年的趋势将颠覆整个行业,并在未来十年重新定义业务,即使数字创新已成为各种规模企业的常规行为."德勤管理咨询新兴技术研究总监兼政府及公共服务首席技术官 ...

  2. 德勤发布2020技术趋势报告,五个新趋势可引发颠覆性变革

    云栖号资讯:[点击查看更多行业资讯] 在这里您可以找到不同行业的第一手的上云资讯,还在等什么,快来! "2020 年的趋势将颠覆整个行业,并在未来十年重新定义业务,即使数字创新已成为各种规模 ...

  3. 对话 a16z 联创 Marc Andreessen:Web3 将产生基础性技术变革

    原题: "硅谷预言家"马克·安德森: 这是三个非常有前途的科技领域 来源:华尔街见闻 (ID: wallstreetcn) 作者:朱雪莹 王眉 作为网景 (Netscape).早期 ...

  4. 智慧城市引发照明新变革 带动产值近千亿元

    根据我国<半导体照明产业"十三五"发展规划><"十三五"节能环保产业发展规划>等政策文件,智慧照明.智慧城市将迎来更大的发展热潮.另外, ...

  5. 计算机产业深度报告:云计算与人工智能开启新一轮技术变革周期

    来源:乐晴智库 概要:每一次的技术迭代都将行业推向新的高度,同时也对产业生态和企业兴衰产生重大影响. 纵观整个IT产业的发展史,从1960年代到现在的2010年代,科技行业历经了大型机时代.小型机时代 ...

  6. 深度解析:服务器架构和技术变革

    文章重点分析服务器架构组成.5G对服务器带来的技术变革(计算边界.场景等),边缘计算.云计算对服务器要求(边缘服务器.AI服务器和云服务器),服务器(白牌机.开源服务器,硬件重构和软件定义)和服务器重 ...

  7. 从桌面到移动:异构计算翻天覆地的技术变革

    摘要:在智能手机上,强大的计算单元,不仅仅是CPU一颗,还包含了GPU.DSP等器件.在传统的台式电脑中,异构计算已经说了好多年了.这篇文章有点长,但值得静下心来慢慢阅读.从桌面到移动,这是关于异构计 ...

  8. 技术变革解锁人文新维度

    2019独角兽企业重金招聘Python工程师标准>>> 这是一个最好的时代.没有人怀疑科技飞速发展,给社会文化生活带来潜移默化的影响和改变. 这一年,代表着科技新浪潮的人工智能开始出 ...

  9. 工作杂谈:由IT行业技术变革 谈当今技术趋势

    IT行业变化日新月异,每次技术变革都会带动一些行业或者应用的兴起,所以无论是创业者,还是程序员,了解IT行业的技术变革和趋势意义重大. 下面是IT行业的几次重大技术变革: 一:PC机时 上世纪70-9 ...

最新文章

  1. 你知道dos和cmd之间的关系以及区别吗?
  2. 革命性移动端开发框架-Flutter时间简史
  3. exchange和域得命名
  4. 深度学习tensorflow框架的张量
  5. jQuery.sap.require
  6. dotnetcore-officeaddin-toolbox : Office 365 Add-in开发人员的工具箱
  7. 香蕉派,蜘蛛侠手臂和USO世界
  8. mqttnet 详解_MQTT协议详解
  9. 实习成长之路:面试官说的MySQL高可用-------主备一致到底是什么?
  10. 【优化分类】基于matlab粒子群算法优化支持向量机分类(多输入多分类)【含Matlab源码 1559期】
  11. mysql中like,limit,union及union all查询
  12. 使用keytool转换签名证书格式,keyStore、jks签名证书相互转换
  13. ansible之when条件语法、处理任务失败、jinja2模板和项目管理
  14. 龙迅LT6911GX
  15. rrpp协议如何修改_RRPP单环
  16. 水 hdu5208 2015-04-20 21:03 36人阅读 评论(0) 收藏
  17. mysql数据库全局搜索_数据库全局搜索
  18. Android WebRTC实现音视频对讲
  19. 利用UE4深度图制作空间开敞度可视化工具
  20. 区块链P2P网络协议演进过程

热门文章

  1. 51单片机入门之五:数码管显示(动态),单片机驱动数码
  2. SpringBoot +WebSocket实现简单聊天室功能实例
  3. javascript 获取当前日期 月份 时间
  4. 计算机网络之7层协议
  5. CSDN上传资源提示:资源上传中断
  6. Migo的物料过账操作
  7. 高数-(01)函数与极限
  8. mysql grant命令详解_MySQL授权命令grant的使用方法详解
  9. 国务院建议探索区块链等技术缩短承兑期限 | 产业区块链发展周报
  10. big sur 虚拟机 网络_推荐收藏系列:一文理解JVM虚拟机(内存、垃圾回收、性能优化)解决面试中遇到问题...