C10K问题_c10lck[通俗易懂]

C10K问题_c10lck[通俗易懂]何为C10K问题?c是指client,而10k则是一万的意思。c10k就是单机同时并发一万个请求。同理c100k则是同时并发十万个请求,如今百万请求也十分常见了。单机能否做到?每个线程占用一定的内存,Linux默认一个线程8M,Windows默认一个线程1M。如果按传统阻塞式IO模式进行处理,

大家好,欢迎来到IT知识分享网。

何为C10K问题?                                                     

       c是指client,而10k则是一万的意思。c10k就是单机同时并发一万个请求。同理c100k则是同时并发十万个请求,如今百万请求也十分常见了。

单机能否做到?

       每个线程占用一定的内存,Linux默认一个线程8M,Windows默认一个线程1M。如果按传统阻塞式IO模式进行处理,一个线程处理一个连接,具体能处理多大的并发量就要看服务器的硬件设备。但是如果使用并发框架,或者go的协程,很容易做到万及以上的并发。 而他们的核心思想就是IO多路复用。

IO多路复用

       为什么要多路复用?cpu的处理是非常快的,所以大部分时间都在IO。阻塞式IO会让CPU大部分时间浪费在等待上,即使多个线程管理多个fd,也会有相当一部分cpu资源浪费。线程越多,内存占用越大,并且CPU的上下文切换也会越频繁,CPU空转,资源得不到有效利用。利用多路复用大大增加了CPU的利用率,同时减少了内存和其他资源的开销。

       怎么多路复用?就是利用一个线程去管理多个fd(file describe)。将多个fd加入函数中,每次调用的时候,传入要检查的fd,如果有就绪的fd就返回,启动线程去按顺序执行。这样就能做到一个线程管理多个fd,我们常见的多路复用模型有select,poll和epoll。

什么是文件描述符?

        文件描述符的英文为File Describe,这里简写为fd。它是用户与内核,设备驱动及硬件设备之间沟通的纽带。在Linux里面一切皆是文件,文件描述符是内核保存的文件描述符表的一个索引。内核在open函数调用后,创建一个文件描述符,并与底层对象相关联,他们可能是一个硬件设备,可能是文件系统,或者某些完整对象。为了与硬件设备通信,于是有了设备驱动,设备驱动向内核提高API,以供内核在响应各种请求时调用。例如read和write函数,他们在响应文件描述符上类似操作时被调用。即用户态与底层设备进行对话的句柄。我们打开一个文件,建立一个socket连接,键盘输入,都会产生一个文件和文件标识符。文件标识符指向内核为每个进程打开文件,是内核高效管理被打开文件创建的索引。

       下图为设备文件的原理图:

                                         C10K问题_c10lck[通俗易懂]

 

       文件又可分为普通文件,目录文件,链接文件和设备文件。系统为每个进程维护了一张文件描述符表,该表是从0开始。所以不同进程文件描述符可能指向同一个文件,也可能指向不同的文件。相同的文件可以被不同的进程打开,也可以被同一个进程重复打开。

select和poll

        都使用非阻塞式的 I/O 。需要从文件描述符列表中找出可执行的 I/O ,然后进行I/O读写。由于是非阻塞的,一个线程可以同时监控一批文件描述符。select与poll有一个很大的一个区别,poll利用了pollfd结构体,并且在内核态中维护了一个链表,改进了select因为bitmap位数组对fd数量受限和bitmap被置位后不可重用的问题。但是select和poll依然最大的缺点是每次调用都要传入所有监听的fd集合,内核再需要对所有的fd进行轮询。当并发量特别大的时候,内核态和用户态之间的数据拷贝与内核对fd的轮询十分浪费系统资源。

epoll

        epoll是select和poll的增强版本,如今Redis,Nginx等就是基于epoll实现的。它能显著提高大量并发中只有少量活跃的情况下CPU的利用率。主要原因是它无需遍历整个被监听的fd集合,只需要遍历那些被内核IO唤醒后就绪的fd集合,效率比select和poll高了许多。要在内核中长久维护一个数据结构来存储fd,并且有查找,插入和删除的操作发生,这对内核的效率产生不小的影响,因此epoll的底层采用红黑树的数据结构来存储fd。这块存储被用户态和内核态共享,少了拷贝的过程。当监听到数据,会对fd进行重排,内核只需要对前面几个有数据的fd进行处理。

go协程

        协程是一个轻量级的线程。GO有M-P-G并发模型,M表示一个核心线程,P代表一个处理器管理M需要的上下文,G代表协程。G必须绑定在P上,P必须绑定在M上。协程的切换其实是比较复杂的,但是主要思想是利用一个核心线程处理多个协程。一个协程只需几KB,对系统的开销是非常小的。我们可以利用go很轻松的达到十万以上的并发量。

                                         C10K问题_c10lck[通俗易懂]

       以上只讲到了部分关于C10K问题的相关解决办法。对于不同系统与编程语言可能有改进方案,但是多路复用的思想应该差不多。

 

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/29725.html

(0)

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信