IO模型
用户空间和内核空间
概念理解
Linux虚拟内存被操作系统分成了两部分,一个是用户空间,一个是用户空间
- 用户空间(User space):用户程序的运行空间,用户程序代码运行的空间
- 内核空间(Kernel space):Linux内核运行空间,内核代码运行的空间
当进程运行在内核空间时就处于内核态,当进程处于用户空间时就处于用户态
-
在Linux 中,执行命令:
ps - 查看系统资源
在%CPU(s)一行,可以看到两个参数:
xxx us -用户空间 xxx sy -内核空间
PIO和DMA
慢速IO设备和内存之间的数据传输方式
PIO
我们读取磁盘文件到内存中,如果数据要经过cpu转发,这种方式成为PIO
DMA
不经过cpu,直接进行磁盘和内存的数据交换,cpu将指令下达给dma控制器,有dma控制器处理数据的传输,此种方式大大减小了cpu的占有率,节省了系统资源
缓存IO和直接IO
缓存IO:
数据->DMA->内核空间->CPU->用户空间
应用:nginx\redis\tomcat应用等(应用比较广泛)
直接IO
数据->DMA->用户空间
应用:mysql
磁盘IO和网络IO访问方式
网路七层结构:
- 7-应用层:http协议
- 4-传输层:TCP/UDP
- 3-网络层:IP/路由器
- 2-数据链路层:交换机
- 1-物理层:基础通信设施
磁盘IO和网络IO都会发生延时,但是网络IO延时大于磁盘IO
传统socket网络编程处理高并发
传统socket问题:高并发情况下下存在阻塞问题,大大降低了系统性能。
同步异步和堵塞非堵塞
同步和异步都会存在堵塞和非堵塞;
同步堵塞:发出请求之后,一直傻等
同步非堵塞:发出请求之后,如果数据没有及时返回,会继续连续请求,进行轮询,直到返回数据
反应器Reactor
反应器设计模式时一种为处理并发服务请求,并将请求提交到一个或者多个服务处理程序的事件设计模式,当客户端请求抵达后,服务处理程序使用多路分配策略,由一个非阻塞的线程来接收所有的请求,然后派发这些请求至i相关的工作线程进行处理。
主要包含内容:
- 初始事件分发器:
- 用于管理事件处理器,定义注册、移除事件处理器等。它还作为Reactor模式的入口调用事件分离器的select方法以阻塞等待事件返回,当阻塞等待返回时,根据事件发生的处理处理程序将器分发给对应的事件处理器处理,即回调事件处理器中的handle_event()方法。
- 同步(多路)事件分离器:
- 无线循环等待新事件的到来,一旦发现有新的事件到来,就会通知初始事件分发器去调取特定的事件处理器。
- 系统处理程序:
- 操作系统中的句柄,是对资源在操作系统层面上的一种抽象,它可以时打开的文件、一个链接(Socket)、Timer等,由于Reactor模式一般使用在网络编程中,因而这里一般指Socket Handler,即一个网络连接(Connection、在Java NIO中的Channel)。这个Channel注册到事件分离器中,以监听Handle中发生的事件,对ServerSocketChannel可以是connect事件,对SocketChannel可以时read、write、close事件等。
- 事件处理器:
- 定义事件处理方法,以供事件分发器回调使用。
Proactor 模式结构
运用于异步IO操作,Proactor模式中,应用程序不需要进行实际的读写过程,它只需要从缓存区读取或者写入即可,操作系统会读取缓存区或者写入缓存区到真正的IO设备。
五种IO模型
同步阻塞IO
传统的IO模型
同步非阻塞IO
默认创建的socket都是阻塞的,非阻塞IO要求socket被设置为noblock,注意这里所说的NIO并非java的NIO库
IO多路复用
即经典的Reactor设计模式,有时也称为异步阻塞IO,Java中的Selector和Linux中的epoll都是这种模型。
有三种模式机制
以下几种方式都时IO多路复用的机制,IO多路复用就是通过一种机制,可以监视多个描述符,一旦某个描述符就绪,能够通知程序进行相应的操作。
redis的IO模型主要是基于epoll实现的,不过它也提供了select和kqueue的实现,默认采用epoll。
- select
- select被循环调用获取激活的socket,一旦socket可读,便调用read函数将socket中的数据读取出来,此种方式时在单线程情况下处理多个IO请求,但是每个IO请求的过程还时阻塞的(在select函数上阻塞),平均时间甚至比同步阻塞IO模型还要长,如果用户线程只注册自己感兴趣的socket或者IO请求,等到数据到来时再进行处理,则可以提高CPU的利用率。
- IO多路复用模型使用了Reactor设计模式实现了这一机制。
- poll
- epoll
异步IO
即经典的Proactor设计模式,也称为异步非阻塞IO
信号驱动IO
不常用