1、单Reactor单线程
定义:单线程主要针对IO操作而言,I/O中的accept
()、read
()、write
()都是在一个线程完成的。
问题:
-
IO操作和业务逻辑处理操作在一个线程上
,大大降低了I/O请求的处理效率。 - 无法充分利用和发挥多核 CPU 的性能。
- 可靠性问题,线程意外终止,或者进入死循环,会导致整个系统通信模块不可用,不能接收和处理外部消息,造成节点故障。
经典实现
redis:
使用单Reactor
单线程,在6.0版本前,核心业务部分使用单线程。官方数据:10万QPS。
6.0版本之后多线程处理网络数据的读写和协议的解析,单线程执行命令。QPS还能提高1~2倍。
为什么用单线程
- 抛开持久化不谈,Redis是纯内存操作,执行速度非常快,它的性能瓶颈是网络延迟而不是执行速度,因此多线程并不会带来巨大的性能提升。
- 多线程会导致过多的上下文切换,带来不必要的开销。
- 引入多线程会面临线程安全问题
单线程的缺点:顺序执行影响后续事件
2、单Reactor线程池
改进:引入了线程池,用来专门处理业务逻辑操作,提升I/O响应速度
,利用多 CPU 的处理能力。
问题:
- 多线程数据共享和访问比较复杂。
- 管理百万级连接、高并发大数据量时,单个
Reactor
线程仍然会效率比较低下。
3、多Reactor多线程(多进程)
改进:扩展了Reactor
。引入多个Reactor
。也称为主从结构。父线程和子线程的职责明确。
扩展Reactor可以是多线程也可以是多进程。
方式 | 资源分配 | 经典实现 |
---|---|---|
多线程 | 线程之间如果涉及资源竞争的话,需要通过锁来保证同步 | netty、memcached等 |
多进程 | 需要进程间通信 | nginx等 |
4、Proactor
对比Reactor
:
-
Proactor
在处理高耗时 IO 时的性能要高于Reactor
,但对于低耗时 IO 的执行效率提升并不明显 -
Proactor
的异步性使其并发处理能力要强于Reactor
-
Proactor
的实现逻辑复杂,编码成本较Reactor
要高很多 -
Proactor
的异步高度依赖于操作系统对于异步的支持。若操作系统对异步的支持不好,Proactor
的性能还不如Reactor
-
Reactor
是同步非阻塞网络模型,Proactor
是异步非阻塞网络模型
问题:Linux 对 AIO支持的不太友好