当前位置: 首页 > article >正文

深入理解 Redis 的文件事件处理器

概述

Redis 的文件事件处理器是基于 Reactor 模式实现的,内部采用 IO 多路复用程序来同时监听多个套接字,当被监听的套接字准备好执行连接应答(accept)读取(read)写入(write)关闭(close)等操作时,与操作相对应的文件事件就会产生,此时文件事件处理器就会调用套接字之前关联好的事件处理器来处理这些事件。

核心组件

文件事件处理器主要由以下4个核心组件构成:

  • 套接字(Sockets):服务器与客户端之间的通信端点;
  • I/O 多路复用程序:负责同时监听多个套接字,并在套接字准备好执行操作时通知文件事件分派器;
  • 文件事件分派器(Dispatcher):接收 I/O 多路复用程序传来的事件,并根据事件类型调用相应的事件处理器;
  • 事件处理器:定义了在特定事件发生时,服务器应该执行的动作。
    文件事件处理器

IO多路复用程序

Redis 的 IO 多路复用程序是通过包装常见的selectepollevportkqueue 这些 I/O 多路复用函数库来实现的, 每个 I/O 多路复用函数库在 Redis 源码中都对应一个单独的文件。
因为Redis 为每个 I/O 多路复用函数库都实现了相同的 API , 所以 I/O 多路复用程序的底层实现是可以互换的。
在这里插入图片描述

事件类型

在 Redis 中,文件事件主要分为两大类:

  • 当套接字变得可读时(客户端对套接字执行 write 操作 或 close 操作),或者有新的可应答(acceptable)套接字出现时(客户端对服务器的监听套接字执行 connect 操作),套接字将产生AE_READABLE 事件;

  • 当套接字变得可写时(客户端对套接字执行 read 操作),套接字将产生 AE_WRITEABLE 事件。

事件处理器

为了实现不同的网络通信需求,Redis 为文件事件编写了多个处理器。

连接应答处理器

当 Redis 服务器初始化时,会将连接应答处理器与服务器监听套接字的AE_WRITEABLE事件关联起来;

当客户端用 connect 函数连接到服务器时,服务器的监听套接字会产生 AE_READABLE 事件;

此时,连接应答处理器会被触发,它负责接受客户端的连接请求,并创建客户端套接字。随后,服务器会将客户端套接字的 AE_READABLE 事件与命令请求处理器关联,以便接收客户端发送的命令请求。

命令请求处理器

当客户端向服务器发送命令请求时,客户端套接字会产生AE_READABLE事件,引发命令请求处理器执行,并执行相应的套接字读入操作;

命令回复处理器

当服务器准备好回复数据给客户端时,它会将客户端套接字的 AE_WRITABLE 事件与命令回复处理器关联。当客户端准备好接收数据时,套接字会产生 AE_WRITABLE 事件,触发命令回复处理器执行,将命令回复写入套接字。

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

完整的连接示例

  1. 假设一个 redis 服务器正在运行,那么服务器监听套接字的AE_READABLE事件就处于监听状态下,并与连接应答处理器关联;
  2. 此时有一个客户端向服务器发起连接,服务器监听套接字将产生AE_READABLE事件,触发连接应答处理器执行,对客户端的连接请求进行应答;然后会创建客户端套接字,并将客户端套接字的AE_READABLE事件与命令请求处理器关联;
  3. 客户端向服务器发送命令请求,客户端套接字将产生AE_READABLE事件,触发命令请求处理器执行,处理器读取客户端的命令,传给相关程序去执行;
  4. 服务器将客户端套接字的AE_WRITABLE事件与命令回复处理器关联,当客户端尝试读取命令回复时,客户端套接字将产生AE_WRITABLE事件,触发命令回复处理器执行,当命令回复处理器将命令回复全部写入到套接字后,服务器就会解除客户端套接字的AE_WRITABLE 事件与命令回复处理器之间的关联。

一次完整的交互流程

总结

Redis 的文件事件处理器是其高性能网络通信的核心。通过单线程的事件驱动模型,Redis 能够有效地处理大量的并发连接和请求,同时保持了代码的简洁性和可维护性。

参考资料
《redis 设计与实现》


http://www.kler.cn/news/305770.html

相关文章:

  • 暗界正方形之谜
  • 【YashanDB知识库】单机升级典型问题及应急措施
  • Spring3-IoC1-IoC容器、基于xml管理bean
  • 【SSRF漏洞】——http协议常见绕过
  • 【React】React18.2.0核心源码解读
  • 乌俄冲突下AI和计算机的使用
  • Spring Boot:现代化Java应用开发的艺术
  • 远程访问电脑共享文件
  • 【Arduino】BNO085 姿态的 3D模型 展示方法(映射到 Unity)
  • Mybatis通用接口-基于Provider
  • 一维稳态与非稳态导热的详细分析
  • 力扣100题——栈和堆
  • 设计模式 装饰模式(Decorator Pattern)
  • 讨论人机交互研究中大语言模型的整合与伦理问题
  • Mysql----索引与事务
  • NLP基础及其代码-BERT系列
  • Ubuntu 24.04 配置 nginx + php-fpm
  • 异常冲突行为和危险识别系统源码分享
  • Rust使用dotenvy读取环境变量
  • 网络通信流程
  • 树和二叉树基本术语、性质
  • 劳特巴赫ICD调试器CMM调用烧录框架固件研究之C语言版本
  • GitHub每日最火火火项目(9.15)
  • 影刀RPA实战:网页爬虫之CSDN博文作品数据
  • 基于C#+SQL Server2008 开发三层架构(CS界面)图书管理系统
  • SQLmap使用请求包进行sql爆破
  • 鹏哥C语言自定义笔记重点(67-)
  • MySQL练手题--公司和部门平均工资比较(困难)
  • 【前端UI框架】VUE ElementUI 离线文档 可不联网打开
  • 后端面试经典问题汇总