Redis(十六,手撸SpringBoot缓存系统

  • 时间事件(time event):时间事件是Redis服务器一些定时执行的操作,比如前面提到的ServerCron函数,是需要在指定时间点上执行的

文件事件

Redis基于Reactor模式开发了自己的网络事件处理器,该处理器被称为文件事件处理器(file event handler)

  • 文件事件处理器使用I/O多路复用程序来同时监听多个套接字,并根据套接字目前执行的任务来为套接字关联不同的事件处理器(即针对每个连接绑定事件处理器,事件处理器不同于文件事件处理器)

  • 当被监听的套接字准备好执行连接应答(accept)、读取(read)、写入(write)、关闭(close)等操作时,与操作相对应的文件时间就会产生,这时文件事件处理器就会调用套接字之前关联好的事件处理器来处理这些事件。

虽然文件事件处理器是以单线程的方式运行(因为Redis是单线程的),但是采用了IO多路复用程序来监听多个套接字(多个连接,对于多个连接有优化),即实现了高性能的网络通信模型,又可以很好地与Redis服务器其他运行的单线程的模块对接(模块都在同一个单线程里面,对接性是很好的),而且保持了Redis内部单线程的设计。

文件事件处理的构成

文件事件处理器总共有4个部分

  • 套接字

  • I/O多路复用程序

  • 文件事件分派器

  • 事件处理器

  • 在这里插入图片描述

  • 文件事件是对套接字操作的抽象,即每当一个套接字准备好执行连接应答、写入、读取、关闭等操作时,就会产生一个文件事件(即将所有套接字操作都抽象文件事件),一个用户连接代表一个套接字,所以可能会有多个套接字。

I/O多路复用是让单线程可以同时监听多个套接字,并且向文件事件分派器传送那些要产生事件的套接字(即发送了命令的用户),但注意这里每次都只传一个套接字,I/O多路复用会有一个阻塞队列来存储要发生事件的套接字,每次以传一个套接字的方式向文件事件分派器发送套接字,只有当上一个套接字产生的事件被处理完后,IO多路复用才会发送下一个套接字。

文件事件分派器接收IO多用复活传来程序传来的套接字,并根据套接字产生事件的类型,调用相应的事件处理器。

服务器会为执行不同任务的套接字关联不同的事件处理器,这些处理器都是一个个的函数,函数定义了服务器应该执行的动作。

IO多路复用程序的实现

Redis的IO多路复用程序的所有功能都是通过包装常见的select、epoll、evport和kqueue这些IO多路复用函数库来实现的(上面那些都是底层系统的多路复用函数库,每个库都是多路复用的一种实现方式),上面封装的每一个多路复用函数库在Redis源码中都是对应一个单独的文件

因为Redis为每一个多路复用函数库都实现了相同的API,所以Redis的多路复用底层实现是可以进行互换的,在编译时自动选择系统中性能最高的IO多路复用函数库作为Redis底层的IO多路复用程序的实现

当套接字发送事件时,IO多路复用程序会监听该事件,并且为套接字关联其需要的事件处理器

事件的类型

IO多路复用程序可以监听多个套接字的事件,事件包括下面的两种

  1. ae.h/AE_READABLE事件

  2. ae.h/AE_WRITABLE事件

这两类事件和套接字之间的对应关系如下

  • AE_READABLE(可读状态):当套接字产生AE_READABLE事件时,表示套接字变得可读,即服务端可以读取套接字里面的内容,即用户端那边进行了write操作、close操作或者connect操作。

  • AE_WRITEABLE(可写状态):当套接字产生AE_WRITEABLE事件时,表示套接字变得可写,即服务端可以往套接字写入内容,给用户端看,即用户端那边进行了Read操作。

IO多路复用程序允许服务器同时监听套接字的两种事件,而且如果一个套接字同时产生了两种事件,如果套接字同时出现了这两种事件时,当IO多路复用程序将套接字传给文件事件派发器时,会优先处理AE_READABLE再处理AE_WRITEABLE,即会优先进行读取套接字(读取套接字内容,往服务器写入数据),然后再往套接字写入(从服务器读取数据,写入到套接字中)

文件事件的处理器

Redis为文件事件编写了多个处理器,这些事件处理器分别用于实现不同的网络通信需求

  • 为了对连接服务器的各个客户端进行应答,服务器要为监听的套接字关联连接应答处理器

  • 为了接收客户端传来的命令请求,服务器要为客户端套接字关联命令请求处理器

  • 为了向客户端传回命令的执行结果,服务器要为客户端套接字关联命令回复处理器

  • 当主服务器和从服务器进行复制操作时,主从服务器都需要关联特别为复制功能编写的复制处理器

连接应答处理器

该处理器用于对连接服务器监听套接字的客户端进行应答(即套接字被服务器监听的客户端)。

当Redis服务器进行初始化的时候,程序会将这个连接应答处理器和服务器监听套接字的AE_READABLE事件关联起来,当有客户端用函数连接服务器监听套接字的时候(即客户端连接上服务器),该套接字就会产生AE_READABLE事件,然后经由IO多路复用程序和文件事件派发器,引发连接应答处理器执行,并执行相应的套接字应答操作。

在这里插入图片描述

命令请求处理器

这个处理器负责从套接字中读入客户端发送的命令请求内容。

当一个客户端通过连接应答处理器成功连接到服务器之后,服务器会将客户端连接的套接字的AE_READABLE事件和命令请求处理器关联起来,当客户端向服务器发送命令请求的时候,套接字就会产生AE_READABLE事件,并且引发命令请求处理器执行,然后执行相应的套接字读入操作(读取用户的输入)。

命令回复处理器

该处理器负责将服务器执行命令后得到的命令回复通过套接字返回给客户端

当服务器有命令回复需要传送给客户端的时候,服务器会将客户端套接字的AE_WRITABLE事件和命令回复处理器关联起来,当客户端那边准备好接收服务器传回的命令回复时,就会产生AE_WRITABLE事件,然后引发命令回复处理器执行,然后执行相应的套接字写入操作。

当命令回复发送完毕之后,服务器就会解除命令回复处理器与客户端套接字的AE_WRITABLE事件之间的关联。

完整的连接过程

Redis初始化,产生连接套接字,服务器开始监听连接套接字,并且该套接字的AE_READABLE事件会关联连接应答处理器,此时客户端连接服务器,连接的是套接字,套接字产生AE_READABLE事件,服务器监听到该事件,IO多路复用程序监听到该事件,将套接字发到阻塞队列里面,然后再给文件事件派发器,再对应给连接应答处理器处理,处理完后就创建客户端套接字,并将客户端套接字的AE_READABLE事件与命令请求处理器进行关联,让客户端可以向主服务器发送命令请求

之后,客户端向主服务器发送命令请求的时候,是发送到新建的客户端套接字,然后命令请求会让套接字产生AE_READABLE事件,该套接字因为关联了命令请求处理器,所以会交由命令请求处理器去执行,此时是会有命令回复的,所以,还需要将套接字的AE_WRITEABLE事件与命令回复处理器进行关联,当客户端那边尝试读取命令回复的时候,对应的客户端套接字将产生AE_WRITEABLE事件,触发命令回复处理器执行,为了不影响之后的AE_WRITEABLE事件的处理,命令回复处理器执行完后,会解除命令回复处理器与AE_WRITEABLE事件的关联

在这里插入图片描述

时间事件

Redis的时间事件分为以下两类

  • 定时事件:让一段程序在指定的时间之后执行一次,比如30秒之后执行。

  • 周期性事件:让一段程序在指定的时间之后执行一次,比如每天晚上12点。

一个时间事件主要由以下三个属性组成:

  • id:服务器为时间事件创建的全局唯一ID(标识号),该ID是从小到大按顺序递增的,即新时间事件的ID会比旧事件的ID号要大

  • when:毫秒精度的UNIX时间戳,记录了时间事件执行时候的时间戳(无论是定时任务还是周期性任务,都会有一个准确执行的UNIX时间戳)

  • timeProc:时间事件处理器,是一个函数,当时间事件到达后,就会调用时间事件处理器去处理事件

一个时间事件是定时事件还是周期性事件,取决于时间事件处理器的返回值:

  • 如果事件处理器返回值是ae.h/AE_NOMORE,那么这个事件就是定时事件,该事件在达到一次之后就会被删除,之后不再被到达,相当于事件过期了

  • 如果事件处理器返回值是一个非AE_NOMORE的整数值,那么这个事件就是周期时间事件,当事件在达到之后,并不会被删除,而是更新when属性,让这个事件在指定时间之后又会到达。

时间事件的实现

服务器将所有时间事件都放在一个无序链表中,每当时间事件执行器运行时,就遍历整个链表,查找所有已到达的时间事件(通过对比当前UNIX时间戳和时间事件的when属性),然后调用时间事件里面的时间事件处理器。

小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频

如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)
img

[外链图片转存中…(img-iQa8TC9r-1710838515583)]
[外链图片转存中…(img-OPWFECYx-1710838515584)]

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频

如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)
[外链图片转存中…(img-yfsfWqjZ-1710838515584)]

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值