IO是什么?
I/O输入/输出(Input/Output),分为IO设备和IO接口两个部分。简单点来说就是输入输出
IO模型种类
阻塞I/O模型: 应用程序会调用一个I/O函数,导致应用程序阻塞,等待数据准备好, 若数据没有未准备就绪,则一直等待 若数据准备好,从内核拷贝到用户空间,I/O函数返回成功
非阻塞I/O模型: 当所请求的I/O操作无法完成时,不让进程阻塞,而是返回一个错误, 这样I/O函数会不断的请求数据是否准备好,没有准备好,继续请求。 直到数据准备好为止。在请求的过程中会占用大量的CPU时间。
I/O复用模型: I/O复用模型会调用select、poll函数,这几个函数也会使进程阻塞,但是和阻塞I/O不同的, 这个函数可以同时阻塞多个I/O操作,而且可以同时对多个读操作,多个写操作的I/O函数进行检测, 直到有数据可读或可写时,才真正调用I/O操作函数。
信号驱动I/O: 两次调用,两次返回。 首先允许套接口进行信号驱动I/O,并安装一个信号处理函数,进程继续运行并不阻塞。 等数据准备好时,进程会收到一个SIGIO信号,可以在信号处理函数中调用I/O操作函数处理数据。
异步I/O模型: 数据拷贝的时候进程无需阻塞 当一个异步过程调用发出后,调用者不能立刻得到结果。 实际处理这个调用的部件在完成后,通过状态,通知和回调通知调用者输入输出操作。
同步I/O引起进程阻塞,直到I/O操作完成 异步I/O不会引起进程阻塞 I/O复用先通过select调用阻塞
Nginx的IO模型
nginx 支持多种并发模型,并发模型的具体实现根据系统平台而有所不同。 在支持多种并发模型的平台上,nginx 自动选择最高效的模型。但我们也可以使用 use 指令在配置文件中显式地定义某个并发模型。
NGINX中支持的并发模型:
select:IO多路复用、标准并发模型。在编译 nginx 时,如果所使用的系统平台没有更高效的并发模型,select 模块将被自动编译。configure 脚本的选项:–with-select_module 和 --without-select_module 可被用来强制性地开启或禁止 select 模块的编译
poll:IO多路复用、标准并发模型。与 select 类似,在编译 nginx 时,如果所使用的系统平台没有更高效的并发模型,poll 模块将被自动编译。configure 脚本的选项:–with-poll_module 和 --without-poll_module 可用于强制性地开启或禁止 poll 模块的编译
epoll
:IO多路复用、高效并发模型,可在 Linux 2.6+ 及以上内核可以使用
kqueue
:IO多路复用、高效并发模型,可在 FreeBSD 4.1+, OpenBSD 2.9+, NetBSD 2.0, and Mac OS X 平台中使用
/dev/poll
:高效并发模型,可在 Solaris 7 11/99+, HP/UX 11.22+ (eventport), IRIX 6.5.15+, and Tru64 UNIX 5.1A+ 平台使用
eventport
:高效并发模型,可用于 Solaris 10 平台,PS:由于一些已知的问题,建议 使用/dev/poll替代。
为什么epoll快?
比较一下Apache常用的select和Nginx常用的epoll
select:
1、最大并发数限制,因为一个进程所打开的 FD (文件描述符)是有限制的,由 FD_SETSIZE 设置,默认值是 1024/2048
,因此 Select 模型的最大并发数就被相应限制了。自己改改这个 FD_SETSIZE ?想法虽好,可是先看看下面吧。
2、效率问题, select 每次调用都会线性扫描全部的 FD 集合,这样效率就会呈现线性下降,把 FD_SETSIZE
改大的后果就是,大家都慢慢来,什么?都超时了。
3、内核 / 用户空间 内存拷贝问题,如何让内核把 FD 消息通知给用户空间呢?在这个问题上 select
采取了内存拷贝方法,在FD非常多的时候,非常的耗费时间。
总结为:1、连接数受限 2、查找配对速度慢 3、数据由内核拷贝到用户态消耗时间
epoll:
1、Epoll 没有最大并发连接的限制,上限是最大可以打开文件的数目,这个数字一般远大于 2048, 一般来说这个数目和系统内存关系很大 ,具体数目可以 cat /proc/sys/fs/file-max 查看。
2、效率提升, Epoll 最大的优点就在于它只管你“活跃”的连接 ,而跟连接总数无关,因此在实际的网络环境中, Epoll的效率就会远远高于 select 和 poll 。
3、内存共享, Epoll 在这点上使用了“共享内存 ”,这个内存拷贝也省略了。
上次更新时间 13 3 月, 2023 at 09:59 上午