美文网首页
Redis经典设计模式-Reactor

Redis经典设计模式-Reactor

作者: Spicy_Chicken | 来源:发表于2021-02-21 23:16 被阅读0次

每个经典的系统服务组件,我们总是能发现其赖以高性能的机制。
所以我们这次也是一样,借着Redis的专题,用实例来写点对Reactor模式的理解。
首先我们免不了俗,简单介绍下Reactor的相关概念:

Reactor对象图 Reator序列图

Reactor模式的角色构成(Reactor模式一共有5中角色构成):

Handle(句柄或描述符,在Windows下称为句柄,在Linux下称为描述符):本质上表示一种资源(比如说文件描述符,或是针对网络编程中的socket描述符),是由操作系统提供的;该资源用于表示一个个的事件,事件既可以来自于外部,也可以来自于内部;外部事件比如说客户端的连接请求,客户端发送过来的数据等;内部事件比如说操作系统产生的定时事件等。它本质上就是一个文件描述符,Handle是事件产生的发源地。

Synchronous Event Demultiplexer(同步事件分离器):它本身是一个系统调用,用于等待事件的发生(事件可能是一个,也可能是多个)。调用方在调用它的时候会被阻塞,一直阻塞到同步事件分离器上有事件产生为止。对于Linux来说,同步事件分离器指的就是常用的I/O多路复用机制,比如说select、poll、epoll等。在Java NIO领域中,同步事件分离器对应的组件就是Selector;对应的阻塞方法就是select方法。

Event Handler(事件处理器):本身由多个回调方法构成,这些回调方法构成了与应用相关的对于某个事件的反馈机制。在Java NIO领域中并没有提供事件处理器机制让我们调用或去进行回调,是由我们自己编写代码完成的。Netty相比于Java NIO来说,在事件处理器这个角色上进行了一个升级,它为我们开发者提供了大量的回调方法,供我们在特定事件产生时实现相应的回调方法进行业务逻辑的处理,即,ChannelHandler。ChannelHandler中的方法对应的都是一个个事件的回调。

Concrete Event Handler(具体事件处理器):是事件处理器的实现。它本身实现了事件处理器所提供的各种回调方法,从而实现了特定于业务的逻辑。它本质上就是我们所编写的一个个的处理器实现。

Initiation Dispatcher(初始分发器):实际上就是Reactor角色。它本身定义了一些规范,这些规范用于控制事件的调度方式,同时又提供了应用进行事件处理器的注册、删除等设施。它本身是整个事件处理器的核心所在,Initiation Dispatcher会通过Synchronous Event Demultiplexer来等待事件的发生。一旦事件发生,Initiation Dispatcher首先会分离出每一个事件,然后调用事件处理器,最后调用相关的回调方法来处理这些事件。Netty中ChannelHandler里的一个个回调方法都是由bossGroup或workGroup中的某个EventLoop来调用的。


根据并发支撑要求等级分为以下几种模式


单线程Reactor模式
这是Redis目前采用的实现方式,通过主线程去响应处理IO事件,逐条执行命令;而其中Redis能够支撑高并发和快速响应的原因如下:

  1. redis是基于内存的,内存的读写速度非常快。
  2. redis是单线程的,省去了很多上下文切换线程的时间。
  3. redis使用多路复用技术,可以处理并发的连接。
单线程Reactor模式
该模式整体流程是:
① 服务器端的Reactor是一个线程对象,该线程会启动事件循环,并使用Selector来实现IO的多路复用。注册一个Acceptor事件处理器到Reactor中,Acceptor事件处理器所关注的事件是ACCEPT事件,这样Reactor会监听客户端向服务器端发起的连接请求事件(ACCEPT事件)。
② 客户端向服务器端发起一个连接请求,Reactor监听到了该ACCEPT事件的发生并将该ACCEPT事件派发给相应的Acceptor处理器来进行处理。Acceptor处理器通过accept()方法得到与这个客户端对应的连接(SocketChannel),然后将该连接所关注的READ事件以及对应的READ事件处理器注册到Reactor中,这样一来Reactor就会监听该连接的READ事件了。或者当你需要向客户端发送数据时,就向Reactor注册该连接的WRITE事件和其处理器。
③ 当Reactor监听到有读或者写事件发生时,将相关的事件派发给对应的处理器进行处理。比如,读处理器会通过SocketChannel的read()方法读取数据,此时read()操作可以直接读取到数据,而不会堵塞与等待可读的数据到来。
④ 每当处理完所有就绪的感兴趣的I/O事件后,Reactor线程会再次执行select()阻塞等待新的事件就绪并将其分派给对应处理器进行处理。
根据Redis单线程处理设计,后续的升级演进,猜测很可能是走单线程多Reactor模式
一个典型的Redis最佳实践是,不推荐使用big key,因为big key的操作会降低Reactor的响应速度。单线程多Reactor模式可以有效将连接动作和读写动作分离,提高吞吐量。TODO:后续的文章会写一个关于redis生产使用过程中,因输入缓冲爆满导致redis崩溃的例子。

线程池Reactor模式

线程池Reactor模式
相对于单线程Reactor模式,Reactor将业务相关的解码+计算+编码工作(非I/O操作),交付给了线程池,Reactor无需关注业务相关的工作,其中线程池中的线程能够复用,也不会引入太多的线程创建和切换的开销;从而简化Reactor的工作,使得Reactor专注accept(),read()和write()等IO业务;

线程池多Reactor模式

线程池多Reactor模式
该模式整体流程是:
① 注册一个Acceptor事件处理器到mainReactor中,Acceptor事件处理器所关注的事件是ACCEPT事件,这样mainReactor会监听客户端向服务器端发起的连接请求事件(ACCEPT事件)。启动mainReactor的事件循环。
② 客户端向服务器端发起一个连接请求,mainReactor监听到了该ACCEPT事件并将该ACCEPT事件派发给Acceptor处理器来进行处理。Acceptor处理器通过accept()方法得到与这个客户端对应的连接(SocketChannel),然后将这个SocketChannel传递给subReactor线程池。
③ subReactor线程池分配一个subReactor线程给这个SocketChannel,即,将SocketChannel关注的READ事件以及对应的READ事件处理器注册到subReactor线程中。当然你也注册WRITE事件以及WRITE事件处理器到subReactor线程中以完成I/O写操作。Reactor线程池中的每一Reactor线程都会有自己的Selector、线程和分发的循环逻辑。
④ 当有I/O事件就绪时,相关的subReactor就将事件派发给响应的处理器处理。注意,这里subReactor线程只负责完成I/O的read()操作,在读取到数据后将业务逻辑的处理放入到线程池中完成,若完成业务逻辑后需要返回数据给客户端,则相关的I/O的write操作还是会被提交回subReactor线程来完成。

【多Reactor线程模式将“接受客户端的连接请求”和“与该客户端的通信”分在了两个Reactor线程来完成】
mainReactor完成接收客户端连接请求的操作,它不负责与客户端的通信,而是将建立好的连接转交给subReactor线程来完成与客户端的通信,这样一来就不会因为read()数据量太大而导致后面的客户端连接请求得不到即时处理的情况。并且多Reactor线程模式在海量的客户端并发请求的情况下,还可以通过实现subReactor线程池来将海量的连接分发给多个subReactor线程,在多核的操作系统中这能大大提升应用的负载和吞吐量。


TODO:等有时间了实现一个多Reactor线程池模式的Demo放上来。

相关文章

  • Redis经典设计模式-Reactor

    每个经典的系统服务组件,我们总是能发现其赖以高性能的机制。所以我们这次也是一样,借着Redis的专题,用实例来写点...

  • Redis与Reactor

    Redis与Reactor 了解了Reactor模式,那么Redis中又是怎么使用Reactor模式的呢? 首先,...

  • Redis的IO多路复用——单线程的理解(Redis6.0之后的

    Reactor设计模式 Reactor 设计模式是一种事件驱动的设计模式,分发器(Dispatcher)使用多路分...

  • 阅读 大话Netty线程模型和Reactor模式

    讲解reactor模式 和 Netty线程模型 设计模式 Reactor模式(反应器设计模式),是一种基于事件驱动...

  • Redis与Reactor设计模式

    最近看了Redis的设计与实现,这本书写的还不错,看完后对Redis的理解有很大的帮助。另外,作者整理了一份Red...

  • Netty理论三:Netty线程模型

    1、Reactor模式:NIO网络框架的典型模式 Reactor是网络编程中的一种设计模式,reactor会解耦并...

  • Redis 单线程模型详解

    Redis 基于 Reactor 模式来设计开发了自己的一套高效的事件处理模型 (Netty 的线程模型也基于 R...

  • IO多路复用Reactor

    简介 reactor是网络编程中基于IO多路复用的一种设计模式,同时reactor模式也是23种设计模式的一种。使...

  • Reactor模式

    什么是Reactor模式 Reactor模式是一种设计模式,它是基于事件驱动的,可以并发的处理多个服务请求,当请求...

  • Redis线程模型

    彻底搞懂Redis的线程模型了解redis的单线程模型工作原理 文件事件处理器 Redis基于Reactor模式开...

网友评论

      本文标题:Redis经典设计模式-Reactor

      本文链接:https://www.haomeiwen.com/subject/eeszxltx.html