聊聊Redis的单线程模型

 更新时间:2022年12月19日 15:10:06   作者:nimo10050  
Redis是单线程,主要是指Redis的网络IO和读写是由一个线程来完成的,但Redis的其他功能,比如持久化、异步删除、集群数据同步等,其实是由额外的线程执行的。这不是本文讨论的重点,有个印象即可

开篇

本文主要来探讨一下 redis 的单线程模型,文章前半部分会先引用某网络课程讲解的内容(图片+语言描述),后半部分是本人粗略阅读 redis 源码后整理出来的一份伪代码,用来验证文中前半部分的内容。

本文对标的 redis 版本是 5.x。

正文

redis 涉及的知识点有很多,展开来讲能聊到操作系统,因此为了方便理解,文中做了很多抽象描述。

文件事件处理器

redis 内部使用了一个叫 文件事件处理器( file event handler)的东西,这个文件事件处理器是 单线程 的,所以才有了 redis 是单线程的这一说法。

文件事件处理器的结构如下图:

它包含 4 个部分:

  • 多个 socketIO
  • 多路复用程序
  • 文件事件分派器
  • 事件处理器(连接应答处理器、命令请求处理器、命令回复处理器)

文件事件处理器 采用 IO 多路复用机制 同时监听多个 socket,根据 socket 上的事件来选择对应的事件处理器进行处理。多个 socket 可能会并发产生不同的操作,每个操作对应不同的文件事件,但是 IO 多路复用程序 会监听多个 socket,会将 socket 产生的事件放入 队列 中排队,事件分派器 每次从队列中取出一个事件,把该事件交给对应的 事件处理器 进行处理。

来看 redis 客户端与服务端的一次通信过程:

1. 接收连接请求:

客户端 socket01 向 redis 的 server socket 请求建立连接,此时 server socket 会产生一个 AE_READABLE 事件,

IO 多路复用程序监听到 server socket 产生的事件后,将该事件压入队列中。

文件事件分派器从队列中获取该事件,交给连接应答处理器。

连接应答处理器会创建一个能与客户端通信的 socket01,并将该 socket01 的 AE_READABLE 事件与 命令请求处理器 关联。

2. 读取请求内容:

假设此时客户端发送了一个 set key value 请求,此时 redis 中的 socket01 会产生 AE_READABLE 事件

IO 多路复用程序将事件压入队列

事件分派器从队列中获取到该事件,由于前面 socket01 的 AE_READABLE 事件已经与命令请求处理器关联,因此事件分派器将事件交给命令请求处理器来处理。

命令请求处理器读取 socket01 的 key value 并在自己内存中完成 key value 的设置。操作完成后,它会将 socket01 的 AE_WRITABLE 事件与命令回复处理器关联。

3. 回复请求:

如果此时客户端准备好接收返回结果了,那么 redis 中的 socket01 会产生一个 AE_WRITABLE 事件,同样压入队列中,

事件分派器找到相关联的命令回复处理器

由命令回复处理器对 socket01 输入本次操作的一个结果,比如 ok,之后解除 socket01 的 AE_WRITABLE 事件与命令回复处理器的关联。

这样便完成了一次通信。

redis 事件处理伪代码

// 入口函数
void aeMain(EventLoop eventLoop) {
    while(true) {
    	// 文件事件处理器
    	aeProcessEvents(eventLoop);  	
    }
}
void aeProcessEvents() {
	// 调用 epoll_wait 函数,等待I/O事件 (IO 多路复用程序)
    int numevents = aeApiPoll(timeval);
    for(int i=0; i< numevents; i++) {
    	// 从队列中取出对应的事件
    	fileEvent = getFromEventQueue(i);
    	// 处理文件事件	(文件事件分派器)
    	processFileEvent(fileEvent);
    	// 处理时间事件。(忽略)
    	processTimeEvent();
    }
}
void processFileEvent() {
	if event == '读事件' {
		// 读处理器
		processReadFile();
	} 
	if event == '写事件' {
		// 写处理器
		processWriteFile();
	}
}

redis 源码

篇幅原因这里就不贴 redis 的源代码,可以用 vscode 等工具打开 redis 安装目录下的 src 目录,通过全局搜索 aeMain 找到入口。

总结

起初当看到别人说 redis 是单线程时,很容易想成 redis 服务端只开启了一个线程用于做所有事情,然而实际上我们所说的 redis 单线程 只是针对 redis 网络请求模块,即文中提到的文件事件处理器。

另外,在第一次看到文中第一张图时,就感觉像是一个线程(IO多路复用程序)负责往队列写数据,另一个线程(文件事件分派器)负责从队列里面读数据,那么 redis 的单线程到底体现在哪里呢?

最后通过一顿操作,翻到了相关源码,粗略一读才明白所谓的事件分派器、队列等等是这样的。

到此这篇关于聊聊Redis的单线程模型的文章就介绍到这了,更多相关Redis单线程内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 深入理解JAVA基础类库中对象Object类

    深入理解JAVA基础类库中对象Object类

    Object类是一个特殊的类,是所有类的父类,如果一个类没有用extends明确指出继承于某个类,那么它默认继承Object类。这里主要总结Object类中的两个:toString()与equals()方法
    2021-09-09
  • Maven中怎么手动添加jar包到本地仓库详解(repository)

    Maven中怎么手动添加jar包到本地仓库详解(repository)

    这篇文章主要给大家介绍了关于Maven中怎么手动添加jar包到本地仓库的相关资料,文中通过图文以及实例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2023-04-04
  • 如何通过java将doc文件转换为docx文件详解

    如何通过java将doc文件转换为docx文件详解

    在数字化时代文档处理成为了我们日常工作和学习中不可或缺的一部分,其中doc和docx作为两种常见的文档格式,各自具有不同的特点和优势,这篇文章主要给大家介绍了关于如何通过java将doc文件转换为docx文件的相关资料,需要的朋友可以参考下
    2024-07-07
  • SpringBoot MyBatis简单快速入门例子

    SpringBoot MyBatis简单快速入门例子

    MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。这篇文章主要介绍了SpringBoot MyBatis快速入门-简单例子,需要的朋友可以参考下
    2021-07-07
  • Java实现图片上传至服务器功能(FTP协议)

    Java实现图片上传至服务器功能(FTP协议)

    这篇文章主要为大家详细介绍了Java实现图片上传至服务器功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-06-06
  • 基于Mybatis Plus实现代码生成器CodeGenerator

    基于Mybatis Plus实现代码生成器CodeGenerator

    这篇文章主要介绍了基于Mybatis Plus实现代码生成器CodeGenerator,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-08-08
  • Springboot Autowried及Resouce使用对比解析

    Springboot Autowried及Resouce使用对比解析

    这篇文章主要介绍了Springboot Autowried及Resouce使用对比解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-06-06
  • springboot如何获取接口下所有实现类

    springboot如何获取接口下所有实现类

    这篇文章主要介绍了springboot如何获取接口下所有实现类问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-09-09
  • 使用SpringBoot和Redis实现高效缓存机制方式

    使用SpringBoot和Redis实现高效缓存机制方式

    本文讲解如何在SpringBoot中集成Redis,通过注解和自定义策略实现高效缓存,优化包括合理过期、预热、避免穿透与击穿,提升应用性能
    2025-08-08
  • SpringBoot 文件或图片上传与下载功能的实现

    SpringBoot 文件或图片上传与下载功能的实现

    这篇文章主要介绍了SpringBoot 文件或图片上传与下载功能的实现,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-02-02

最新评论