Reactor模式详解及redis如何使用

2022/01/06 1166点热度 0人点赞 0条评论

大神Doug Lea在http://gee.cs.oswego.edu/dl/cpjslides/nio.pdf 里详细介绍了java nio的实现思路,里面也详细介绍了reactor模式,后文统一称为老爷子的文章。

看这篇文章建议先了解下linux中的文件描述符与套接字socket redis中的IO多路复用select和epoll

传统阻塞I/O模型

以上图片摘自大神Doug lea 的nio。

特点

  • 一个后端线程只能处理一个客户端请求

  • 采用I/O阻塞的模式处理客户端请求

分析

  • 随着并发量上升,后端资源有限的情况下会占用大量的线程资源;

  • 如果后端资源有限,那么后面来的客户端请求会阻塞;

  • 线程的创建和销毁也会占用大量的cpu资源;

改进

  • 可以引入线程池,减少线程的重复创建和销毁

reactor模式

在https://en.wikipedia.org/wiki/Reactor_pattern中。

The reactor design pattern is an event handling pattern for handling service requests delivered concurrently to a service handler by one or more inputs. The service handler then demultiplexes the incoming requests and dispatches them synchronously to the associated request handlers

梳理下关键点:

  • 是一种事件驱动处理模式

  • 处理一个或多个输入并发请求

  • 服务器通过handler对请求进行多路分发,分发给request handlers

在上一篇中讲了I/O多路复用,

在老爷子的文章里对reactor pattern有如下说明:

  • reactor 通过分发IO事件给对应的handler处理;

  • handlers执行非阻塞操作

  • 通过绑定处理器handlers处理对应的事件进行管理(这个就是acceptor)

然后老爷子又分了三种reactor模式

单线程reactor模型,也是最基本的reactor模式

java nio是这么支持的

  • channels 连接到支持非阻塞读取的文件、socket等

  • buffers 可以被channels读取或写入的缓冲区

  • selectors 识别出哪个channels中有io事件

  • selectionKey io事件状态和处理器的绑定

老爷子在文档里也举了一个例子,这里不再说明。

  • 这个模式里,reactor负责分发(dispatch)

  • 然后由启动Acceptor调用对应的Handler

  • 由Handler进行网络io读、业务处理,网络io写;

redis5.0之前都是使用类似这种模式;

  • aeMain进行loop

  • aeProcessEvents进行事件捕获与分发

  • 通过aeApiPoll 捕获事件

  • 通过事件类型掩码mask进行事件处理(分发即处理)

  • 通过fe->rfileProc和fe->wfileProc 执行然后又重新注册新的事件

单reactor多线程处理

  • 在这个模式里reactor只负责分发

  • 业务逻辑都交给了线程池处理

在这个模式里reactor还是单线程,不过reactor获取到的任务会分发给线程池处理(redis中实现时,主线程也是一条工作线程)

redis6.0使用这种模式的变种

  • aeMain进行loop

  • aeProcessEvents进行事件捕获与分发

  • 通过fe->rfileProc和fe->wfileProc 执行然后又重新注册新的事件

  • 通过aeApiPoll 捕获事件(就是上一篇讲的IO多路复用机制)

  • 捕获后分发给线程池(轮询分发)

  • 线程池处理分发的任务(主线程是线程池第一个线程)

  • 通过fe->rfileProc和fe->wfileProc 执行然后又重新注册新的事件

  • 主线程等待所有的线程处理完,然后进入下一个轮询

多reactor多线程处理

nginx应该是使用这种模式

最后奉上之前画的io处理流程图

redis系列文章

redis源码阅读-入门篇

redis源码阅读二-终于把redis的启动流程搞明白了

redis源码阅读三-终于把主线任务执行搞明白了

redis源码阅读四-我把redis6里的io多线程执行流程梳理明白了

redis源码阅读五-为什么大量过期key会阻塞redis?

redis源码六-redis中的缓存淘汰策略处理分析

阅读redis源码的时候一些c知识

linux中的文件描述符与套接字socket

redis中的IO多路复用select和epoll

redis的key过期了还能取出来?

本文是Redis源码剖析系列博文,有想深入学习Redis的同学,欢迎star和关注;
Redis中文注解版:https://github.com/yxkong/redis/tree/5.0
如果觉得本文对你有用,欢迎一键三连;
同时可以关注微信公众号5ycode获取第一时间的更新哦;

yxkong

这个人很懒,什么都没留下