2019/05/27 IO复用模型原理

在这里插入图片描述
内核级功能,i/o
在这里插入图片描述
prefork,两级结构,一个主进程开启若干个子进程,每个子进程来响应用户请求
worker是三级结构,主进程生成若干子进程,子进程生成多个线程,每个线程来响应用户请求
event是以worker类似,只不过增加了一个监控线程,来回收没有人访问的线程
apache再并发达到过万的时候,性能就受到影响
nginx可以达到3万的并发,为什么性能好,就是因为io模型来决定的

在这里插入图片描述
磁盘里的io
事实上,再对于网络中的应用来传输数据的时候,本质上也算是IO,因为在网络编程的时候,(http,python脚本程序,来实现socket通讯),网络通讯的时候也是经过读写机制的,只不过在经过网络的时候,是通过发到socket文件里去的,你发数据到远程主机,也是通过socket文件,对方也是通过socket来接收远程数据
网路也算是一种IO

在这里插入图片描述
一个远程用户请求一个html文件,请求到达网卡,根据tcp/ip分层,是应该吧mac层,ip报头,传输层,tcp报文头部到达应用层,就到达了nginx进程(工作在用户空间,但是工作在用户空间的进程是不能直接访问硬件的(要想把文件返回给用户,就需要由内核来完成这个工作,内核有权力去访问磁盘,磁盘把文件先返回给内核,有一个缓冲区,
再通过内核缓冲区把文件复制到应用程序nginx的缓冲区,然后封装报文头部,再发送过去
进行了4个过程

在这里插入图片描述
显然从磁盘上获取数据更久
内核空间,复制到nginx的内存空间,因为都是再内存里,所以速度是很快的
再快也比不上cpu,cpu是最快的,内存的数量再怎么着,也慢了一个数量级

在这里插入图片描述
nginx收到请求后,转发请求到内核,之后,不会傻等着,这就是涉及到IO模型的问题
在这里插入图片描述
同步(synchhronous/异步(asynchronous,阻塞/非阻塞
NFS,数据库,有同步异步,(是把数据立即写磁盘,还是等会再写
nginx的同步异步更关注的是消息通信机制
同步(synchhronous,调用者等待被调用者返回消息(调用者主动地去问被调用者是否完成,调用者消耗的精力更多一些)
异步(asynchronous,被调用者发个消息给调用者,表达事情已经做完了,对于调用者来讲更加省心一点

在这里插入图片描述
阻塞和非阻塞的关注点在于 ,调用者发任务给被调用者之后,到底是干等着,还是去忙别的事情
如果是阻塞,就是当调用者发送任务给被调用者之后,傻等着,什么时候被调用者做完之后才能去做别的事情
非阻塞,当调用者发送一个任务给被调用者,被调用者在没有完成任务之前,调用者仍然可以做别的事情,
可以不挂起,不傻等着
同步阻塞,比较消耗精力,只能把事情一件件做完
同步非阻塞,虽然没有阻塞,但是因为是同步机制,就并没有很好地利用这个条件
异步阻塞,洗完了通过你,阻塞(还在等着它),实际上什么也做不了,只是在那里等待浪费资源
异步非阻塞,效率最好,把任务下达了,就可以该做什么就去做什么了

在这里插入图片描述
在生产中用到的IO模型,真正用到的有5种
在这里插入图片描述
当用户发起请求,用户进程希望得到一个数据(因为用户进程没有权限,就要去系统调用,内核中的API接口,让内核来帮忙完成),这时候有两个阶段,第一阶段把数据从磁盘上把文件获取到内核空间,从内核复制到用户空间的缓存区中,这个就是对应画图的第4步
用户进程发送任务给内核之后,就一直在那里等待,同步阻塞,只能得到任务完成,最终得到数据
用户进程想要工作就需要把3,4步做完了,返回一个成功结果,这样用户进程得到数据了,就可以做别的事情去了,在这期间什么也做不了,是阻塞的状态

在这里插入图片描述
在这里插入图片描述
访问一个应用程序,应用程序本身的效率高还是内核效率高,让你感受更快一些,一般来讲用户是访问应用程序不是去访问内核,内核是为应用程序提供服务的,所以相对来讲,应用程序反应的响应速度更快
如果应用程序干的活多了,负担较重,自然对于用户的响应就慢了
如果内核做的事情多了,就变相减轻了应用程序干的活

在这里插入图片描述
同步,意味做完了任务不通知你,只能自己去看
当需要一个资源,就发送请求,到内核,内核帮你完成,但是完成不完成不知道,就一次次地去询问
数据从磁盘放到内核的时候认为完成(实际上没做完,我们得到数据是需要在用户进程的内存空间里发送到用户)
在磁盘复制到用户空间的过程中,用户是并不了解的(会不断地去询问是否完成)
询问一次就要消耗CPU就做了很多无用功

在这里插入图片描述
在这里插入图片描述
**之前的是每个进程发送请求给系统调用,跑到内核,内核去磁盘上读取数据
每个进程都是直接去访问系统,调用获取数据的,这样对内核来讲,是直接和进程打交道的
IO多路复用是专门找一个代理人叫select,(select相当于一个办事的大屏幕,当内核从磁盘拿到数据后,就通知某个用户进程,任务完成了)
在第一个阶段,用户的进程是阻塞在select这里的
后续的阶段,是用户进程需要等待数据从内核空间中复制到用户空间来完成的
实际上也是一种阻塞状态,只不过阻塞的位置和场景并不一样
select,利用IO多路复用,可以并发地响应用户请求,相当于专门的人接待客人,不用去和后面打交道
**
在这里插入图片描述
虽然性能上没有提高,但是有专门的select模块,来并发响应用户请求
可以多路请求复用这个select(实际上并不是select才能实现这个功能,还有poll,也能使用系统调用功能,能够实现类似的功能
IO复用模型应用场景主要在如下环境中使用

在这里插入图片描述
一个文件需要占用一个描述符(比如交互输入和网络套接字)
最多的是下面这个场景,tcp服务器要处理多个套接字的时候,比如有多个用户发送请求,nginx还是apache都同时收到很多用户请求,这时候就会打开多个套接字请求来进行处理,有的是监听套接字,或者已经链接上了(监听状态和链接状态)

在这里插入图片描述
在这里插入图片描述
信号驱动IO模型,有些异步特性,调用者不需要主动去问被调用者,被调用者做完,主动通知你
内核从磁盘读取数据的时候,第三个过程,还没得到数据,进程就可以做点别的事情,
内核把数据准备好之后通知用户进程,接下来,第4个状态
内核数据复制到用户进程中,这个过程用户进程是处于等待的
所以有一部分实现了异步,有一部分实现了同步

在这里插入图片描述
在这里插入图片描述
用户发起请求,用户进程,告诉内核需要数据,内核从磁盘获取数据,从内核空间把数复制到用户空间,这个用户程序一直在持续运行,一直没有阻塞,一直在忙自己的,所有的工作交由内核做
用户程序发现很不操心,内核做的事情较多一点,进程做的时候越少,同时就能响应更多用户请求

在这里插入图片描述
5种IO模型的总结
在这里插入图片描述
1.同步一直在阻塞,什么时候内核把事情做完了,才能做其他的事情,同步阻塞模型
2.同步非阻塞模型,不是完全非阻塞,第三个简单不阻塞,但是同步,就需要不断地去询问是否完成
表明上不阻塞,其实还不如阻塞,第4阶段,什么时候把内核空间数据复制到用户进程空间,就算结束
3.IO复用模型,这两个阶段其实都是阻塞的,只不过对于前面的阶段,阻塞在select上面,把任务阻塞在select。其他进程不用直接联系内核(实际还是阻塞,无非是换个地方)
4.信号驱动模型,第三阶段不阻塞,可以做别的事情,相对来讲性能提高了,第4阶段阻塞,自己去吧内核空间数据复制到用户空间
5.最理想的异步模型,
越往左偏同步的,右边是异步
重点掌握同步,异步,阻塞,非阻塞

在这里插入图片描述
在这里插入图片描述
select,poll,epoll.kqueue,/dev/poll/iocp,都是和IO复用相关的
其中select是跨平台的,linux,windows也是支持的,用的 IO复用模型
poll是改进版的select(可以理解为select和poll是一个级别的,没有什么根本性变化)
EPOll相对select和poll来讲有极大的提升,具用的是信号驱动IO模型的一些特性,性能就相对来讲是更好一点。
locp是windows实现的,用的是真正的异步模型

在这里插入图片描述
select,poll,epoll都可以面对多个用户并发请求,相当于一个代理人,手机很多 的用户请求过来,手机以后,它去帮你从内核到磁盘上得到数据,但是这个数据有没有准备好,是不一样的,select和poll用 的是遍历机制。select和poll相当于代理好多人的请求,有些用户数据准备好了,但是还有很多用户数据没有准备好,那就需要和进程用户打交道,并且告诉对方
(如何知道谁的进程准备好,select和poll是遍历的,就需要一个个去找,(比如用户询问,数据有没有好,你说等会,你需要去查,一个个去查,到最后结束告诉你结果,这样全表扫描,效率是偏低的))
epoll是异步的机制,就有信号驱动的一些特性,数据准备好后,会主动通知你去拿,相对来讲效率更高
select和poll
用户请求越多,遍历时间就越长
epol因为是回调机制,和你的请求个数是没有关系的
slect最大并发数是1000个,内核来决定的,poll和epoll是无上限的

在这里插入图片描述
在这里插入图片描述
变相描述了select和poll,epoll
select最大并发1000,修改这个值只能重新编译内核 了
水平触发
跨平台使用
poll
只支持linux
无限制并发
这两个都属于同步IO
epoll属于异步IO
支持水平触发和边缘触发
水平触发通知多次
边缘触发只通知一次

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
epoll支持MMAAP (内存映射)
数据在磁盘上存放,是以文件系统来组织的(有节点表,inode),数据和节点表是相分离的,通过节点表层层地去目录结构找到最终数据,相对效率不是很高
可以在磁盘上划一块空间,这个空间就是文件,把他映射到内存里,让它在内存中有一块一模一样的大小空间,需要一一对应,假设这个磁盘空间是16M,内存也是16M,每个字节也一一对应,将来访问数据的时候,就可以直接访问内存空间,这个内存空间是和磁盘一一对应的,这样就不要分析节点表,一层层下去找了,比如找第100个字节,就直接可以找到,不用通过inode层层去找

在这里插入图片描述
直接内存映射,写数据,因为是直接对应的关系,
之前修改index文件,需要现在内存中进行修改,改了之后再复制到磁盘里去

在这里插入图片描述
为什么nginx性能好,是因为nginx用 就是epoll的方式
而apache用的是select的方式,所以性能相对nginx要差一些

在这里插入图片描述
支持更多并发链接就是因为使用的是epoll,但是虽然号称,并发无限,但是官方最多指出也是30000的并发
即使用epoll,也不可能去消耗所有的资源

在这里插入图片描述
每个链接过来是要消耗系统资源的,消耗的时候,实际上也有一定的极限
还有一个端口号消耗的问题,
有时候会承担一个代理服务器 的角色
nginx不仅可以做web服务器,还可以做为反向代理
lvs是工作在内核级,nginx是应用层的,代替远程客户端来访问后端服务器的,既然是客户端,同时并发请求连接到服务器,太多的用户就要打开太多 的端口号,是客户端就需要消耗端口号,tcp端口号最多才65535,有一些还是给服务预留的,真正的端口最多也就3万到6万 多

在这里插入图片描述
nginx服务器并发访问达到2,3万已经达到j极限了
如果并发实在太大,就需要用到lvs,多台nginx

在这里插入图片描述
在这里插入图片描述
nginx也开始有商业化了,社区版和商业版
,org组织,.com商业公司
淘宝的Tengine,就是用nginx做的二次开发
openresty

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值