《Redis设计与实现》第十二章总结:事件

4 事件

Redis服务器是一个事件驱动程序,需要处理两类事件,分别是文件事件和时间事件:
在这里插入图片描述

4.1 文件事件

文件事件处理器:基于Reactor模式的网络事件处理器
在这里插入图片描述

4.1.1 文件事件处理器的构成

socket、I/O多路复用程序、文件事件分派器、事件处理器:
在这里插入图片描述
IO多路复用程序通过队列向文件事件分派器传送套接字,当上一个socket处理完毕之后,才能传送下一个socket;每一个处理器都是一个函数:
在这里插入图片描述

4.1.2 IO多路复用程序的实现

通过包装select、epoll、evport、kqueue这些常见的IO多路复用函数库来实现的,每个函数库对应一个源文件

IO多路复用程序可以选择不同的函数库来作为底层实现,因为Redis为每个库实现了相同的API:
在这里插入图片描述
性能:evport>epoll>kqueue>select,#include宏中定义了规则:程序编译时会自动选择性能最高的库作为IO多路复用程序的底层实现

4.1.3 事件类型

ae.h/AE_READABLE、ae.h/AEWRITABLE:
在这里插入图片描述
同时出现时,优先处理AE_READABLE,即服务器先读后写

4.1.4 API

在这里插入图片描述

4.1.5 常见文件事件处理器

连接应答处理器、命令请求处理器、命令回复处理器、复制处理器(不常用)作用:
在这里插入图片描述

  • 连接应答处理器

networking.c/acceptTcpHandler函数为连接应答处理器,用于对连接服务器监听socket的客户端进行应答;具体实现为sys/socket.h/accept函数的包装

流程:
在这里插入图片描述

  • 命令请求处理器

networking.c/readQueryFromClient函数为命令请求处理器,用于从socket中读入客户端发送的命令请求;具体实现为unistd.h/read函数的包装

流程:
在这里插入图片描述

  • 命令回复处理器

networking.c/sendReplyToClient函数为命令回复处理器,用于将服务器执行命令后得到的命令回复通过socket返回给客户端,具体实现为unistd.h/write函数的包装

流程:
在这里插入图片描述

  • 一次完整的客户端与服务器连接事件示例
    在这里插入图片描述
4.1.6 时间事件

分为定时事件和周期性事件:
在这里插入图片描述
时间事件主要属性:id、when、timeProc
在这里插入图片描述
一个时间事件是定时事件还是周期性事件取决于时间事件处理器的返回值:
在这里插入图片描述

4.1.6.1 实现

使用无序(不按when排序,按id排序)链表保存时间事件,每当时间事件执行器运行时,遍历整个链表,查找所有已到达的时间事件,并调用相应的事件处理器,复杂度为O(N)

例子:
在这里插入图片描述
注意:使用无序链表并不影响时间事件处理器的性能
在这里插入图片描述

4.1.6.2 API

在这里插入图片描述

4.1.6.3 时间事件应用实例:serverCron函数

执行定期操作,检查和调整自身的资源和状态,确保服务器可以长期、稳定地运行

主要工作:
在这里插入图片描述

4.1.7 事件的调度与执行

ae.c/aeProcessEvents函数:
在这里插入图片描述
将aeProcessEvents函数置于循环内处理:
在这里插入图片描述
事件角度下的服务器运行流程:
在这里插入图片描述
注意:事件之间不会出现抢占

一次完整的事件调度和执行过程:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值