-
单进程:易陷入阻塞,导致请求被大量的丢弃或者陷入等待;
-
多进程:每一个进程响应一个用户请求.但是每个进程的地址空间是相互独立的,进程间的数据大多数是重复的,内存利用效率低;
-
对于进程来说,每一个进程在等待
IO
的时刻,都需要为进程维护一个数据结构,用于区别不同的进程IO
状况,早期是通过select
的方式来管理这些数据结构的,select
最多支持1024
个进程管理; -
线程:
thread
:Light Weight Process
:Linux支持不同的线程库;- 每个线程响应一个用户请求:
- 线程依然需要进行切换,切换相对于进程属于轻量级;
- 同一个进程的线程可以为共享线程的诸多资源,例如打开的文件;
- 对于内存的需求较之进程较小;
-
CPU
等待的方式包括:- 忙等:也就是需要间隔一段时间来查询线程的状态,这称为忙等,忙等需要借助于
spin lock
自旋锁来实现; - 如果一个进程内部存在多个线程,在调度线程的过程中,容易出现线程抖动;
- 忙等:也就是需要间隔一段时间来查询线程的状态,这称为忙等,忙等需要借助于
-
多进程多线程模型:
- 用于降低单个进程管理多个线程可能出现的线程抖动的问题;
- 可以通过
CPU
绑定技术,来实现绑定进程在某个CPU
上面,来降低进程切换的开销;
-
多线程,多请求:
- 也就是通过一个线程响应多个请求的方式,对于这种方式在响应请求的过程中,线程需要
IO
时,是不能够陷入阻塞的,因为一个线程阻塞,意味着多个线程都需要陷入阻塞,内核需要通过多路IO
的机制来通过某些线程请求的数据已经就绪;
- 也就是通过一个线程响应多个请求的方式,对于这种方式在响应请求的过程中,线程需要
-
IO
动作的执行:- 进程是无法直接操作
IO
设备的,必须通过系统调用来请求kernel
来协助完成IO
动作;
- 进程是无法直接操作
-
内核会为每个
IO
设备维护一个buffer
, 对于输入而言,wait
数据输入至buffer
需要时间,而从buffer copy
数据到进程地址空间也是需要时间的;
-
IO
等待的五种模型: -
block IO
:表示阻塞式IO
,也就是陷入阻塞,进行等待;
-
nonblocking IO
:表示非阻塞IO
; -
在第一个阶段,内核在准备数据的过程中,通过询问机制来判断数据是否准备完成,这个阶段是非阻塞的,但是在第二个节点仍然是阻塞的;
-
IO multiplexing
:表示IO
复用技术,当一个进程需要处理多个IO
的时候,就需要进行复用; -
这个过程分为两步,第一次系统调用用于请求数据,直到数据复制到内存缓冲区,第二次还需要发起系统调用来同步数据, 这一段依然是阻塞的;
-
signal driven IO
:依靠信号驱动的IO
模型; -
第一个阶段用于进行数据的准备工作,这个工作准备完成后,内核通过通知机制通知进程,
IO
已经就绪,第一个阶段不进行阻塞,但是在第二个界限进行阻塞;这种机制,是通过函数的回调机制实现的; -
关于上述通知的两种机制:
- 水平触发:也就是再通知一次之后,过一段时间,依然会进行通知;
- 边沿出发:仅仅通知一次,之后不在进行通知;
-
asynchronous IO
:表示异步IO
,不会导致请求进程阻塞; -
表示
IO
的两段都是不进行阻塞的,所以必须通过信号机制来通知;
-
这几种技术的组合方式:
-
对于同步阻塞
IO
使用的技术是read/write
系统调用; -
对于异步阻塞
IO
使用的技术是IO multiplexing
技术; -
对于同步非阻塞
IO
使用的是read/write
并且返回O_NOBLOCK
; -
对于异步非阻塞
IO
使用的技术是AIO
,也就是异步IO
技术;\ -
对于上面几种技术的一个对比
- 如果工作在同步阻塞模型下,那么从磁盘到内核空间,以及从内核空间到进程都是需要进行等待的,这种模型是不能够同时响应多个请求的;
- 如果工作在异步阻塞模型下:磁盘到内核空间阻塞,内核空间到进程是非阻塞的,可以响应多个用户的请求;
IO
复用模型下:同样的两段都是阻塞的,使用一个进程响应多个用户的请求,性能会十分差,可以使用多进程响应多个用户请求;
-
select(1024),poll()
这两个函数是用于实现多路复用技术的,用于监控一段针对于不同IO
请求的文件,select
默认最迟最多1024
个文件; -
基于事件驱动的
IO
模型,可以使用一个线程,响应多个用户的请求,事件驱动的实现需要使用epoll
来实现,freeBSD
使用的是kqueue
来实现的; -
还有一种机制是内核共享自己的缓冲区,这个成为内存映射;
-
异步
IO
表示的含义就是,数据准备需要准备到进程或者线程的缓冲区,在进行通知; -
nginx
支持AIO mmap event-driven
,多用于反向代理; -
Web
集群的设计: -
前端首先应该实现动态内容和静态内容分离,动态内容交给
HTTPD
服务器,静态内容交给Nginx
服务器,前端使用独立的nginx
服务器实现动静分离,如果动态内容的速度比较慢,对于较少修改的动态内容,应该使用缓存服务器,用于缓存动态内容; -
Mysql
服务器首先应该实现读写分离,并且应该为Mysql
提供缓存服务器,例如memcached
,或者redis
,并且可以为多个缓存服务器提供读的负载均衡器; -
动态的内容,首先需要进行编译,应该为
PHP
提供Xcache
模块,用于进行缓存,
IO复用的相关知识
最新推荐文章于 2024-08-28 20:04:53 发布