理解Redis单线程快的原因

article/2025/9/29 17:01:15

看过相关Redis基础的同学可以知道Redis是单线程的,很多面试题也很可能会问到“为什么Redis是单线程的还那么快”。

单线程的内部的原理。

本力求简单讲清每个知识点,希望大家看完能有所收获。

这里就简单回顾一下吧:

I/O多路复用的特点是通过一种机制一个进程能同时等待多个文件描述符,而这些文件描述符其中的任意一个进入读就绪状态、等等,select/epoll函数就可以返回。

select/epoll的优势并不是对于单个连接能处理得更快,而是在于能处理更多的连接。
说白了,使用IO多路复用机制的,一般自己会有一套事件机制,使用一个线程或者进程监听这些事件,如果这些事件被触发了,则调用对应的函数来处理。

Redis服务器是一个事件驱动程序,主要处理以下两类事件:

文件事件:文件事件其实就是对Socket操作的抽象,Redis服务器与Redis客户端的通信会产生文件事件,服务器通过监听并处理这些事件来完成一系列的网络操作

时间事件:时间事件其实就是对定时操作的抽象,前面我们已经讲了RDB、AOF、定时删除键这些操作都可以由服务端去定时或者周期去完成,底层就是通过触发时间事件来实现的!

文件事件

Redis开发了自己的网络事件处理器,这个处理器被称为文件事件处理器。

文件事件处理器由四部分组成:
在这里插入图片描述

文件事件处理器组成
文件事件处理器使用I/O多路复用程序来同时监听多个Socket。当被监听的Socket准备好执行连接应答(accept)、读取(read)等等操作时,与操作相对应的文件事件就会产生,根据文件事件来为Socket关联对应的事件处理器,从而实现功能。

要值得注意的是:Redis中的I/O多路复用程序会将所有产生事件的Socket放到一个队列里边,然后通过这个队列以有序、同步、每次一个Socket的方式向文件事件分派器传送套接字。也就是说:当上一个Socket处理完毕后,I/O多路复用程序才会向文件事件分派器传送下一个Socket。

首先,IO多路复用程序首先会监听着Socket的AE_READABLE事件,该事件对应着连接应答处理器
可以理解简单成SocketServet.accpet
在这里插入图片描述
监听着Socket的AE_READABLE事件

此时,一个名字叫做3y的Socket要连接服务器啦。服务器会用连接应答处理器处理。创建出客户端的Socket,并将客户端的Socket与命令请求处理器进行关联,使得客户端可以向服务器发送命令请求。

相当于Socket s = ss.accept;,创建出客户端的Socket,然后将该Socket关联命令请求处理器

此时客户端就可以向主服务器发送命令请求了
在这里插入图片描述
客户端请求连接,服务器创建出客户端Scoket,关联命令请求处理器
假设现在客户端发送一个命令请求set name hello,world,客户端Socket将产生AE_READABLE事件, 引发命令请求处理器执行。处理器读取客户端的命令内容,然后传给对应的程序去执行。客户端发送完命令请求后, 服务端总得给客户端回应的。此时服务端会将客户端的Scoket的AE_WRITABLE事件与命令回复处理器关联。

在这里插入图片描述

客户端的Scoket的AE_WRITABLE事件与命令回复处理器关联
最后客户端尝试读取命令回复时,客户端Socket产生AE_WRITABLE事件,触发命令回复处理器执行。当把所有的回复数据写入到Socket之后,服务器就会解除客户端Socket的AE_WRITABLE事件与命令回复处理器的关联。

最后以《Redis设计与实现》的一张图来概括:

在这里插入图片描述
Redis事件交互过程

时间事件

持续运行的Redis服务器会定期对自身的资源和状态进行检查和调整,这些定期的操作由serverCron函数负责执行,它的主要工作包括:

更新服务器的统计信息(时间、内存占用、数据库占用)

清理数据库的过期键值对

AOF、RDB持久化

如果是主从服务器,对从服务器进行定期同步
如果是集群模式,对进群进行定期同步和连接

Redis服务器将时间事件放在一个链表中,当时间事件执行器运行时,会遍历整个链表。时间事件包括:
周期性事件(Redis一般只执行serverCron时间事件,serverCron时间事件是周期性的)

时间事件和文件事件

文件事件和时间事件之间是合作关系,服务器会轮流处理这两种事件,并且处理事件的过程中不会发生抢占。
时间事件的实际处理事件通常会比设定的到达时间晚一些.

在《Redis设计与实现》中各用了一章节来写客户端与服务器,我看完觉得比较底层的东西,也很难记得住,所以我决定总结一下比较重要的知识。如果以后真的遇到了,再来补坑~
服务器使用clints链表连接多个客户端状态,新添加的客户端状态会被放到链表的末尾
在这里插入图片描述
客户端–链表
一个服务器可以与多个客户端建立网络连接,每个客户端可以向服务器发送命令请求,而服务器则接收并处理客户端发送的命令请求,并向客户端返回命令回复。

Redis服务器使用单线程单进程的方式处理命令请求。在数据库中保存客户端执行命令所产生的数据,并通过资源管理来维持服务器自身的运转

Redis客户端

客户端章节中主要讲解了Redis客户端的属性(客户端状态、输入/输出缓冲区、命令参数、命令函数等等)

typedef struct redisClient{//客户端状态的输入缓冲区用于保存客户端发送的命令请求,最大1GB,否则服务器将关闭这个客户端
sds querybuf;//负责记录argv数组的长度。
int argc;// 命令的参数
robj **argv;// 客户端要执行命令的实现函数
struct redisCommand *cmd, *lastcmd;//记录了客户端的角色(role),以及客户端所处的状态。 (REDIS_SLAVE | REDIS_MONITOR | REDIS_MULTI) 
int flags;//记录客户端是否通过了身份验证
int authenticated;//时间相关的属性
time_t ctime; /* Client creation time */ 
time_t lastinteraction; /* time of the last interaction, used for timeout */
time_t obuf_soft_limit_reached_time;//固定大小的缓冲区用于保存那些长度比较小的回复
/* Response buffer */
int bufpos;
char buf[REDIS_REPLY_CHUNK_BYTES];//可变大小的缓冲区用于保存那些长度比较大的回复
list *reply; //可变大小缓冲区由reply 链表和一个或多个字符串对象组成
//...
}

服务端

服务器章节中主要讲解了Redis服务器读取客户端发送过来的命令是如何解析,以及初始化的过程。
服务器从启动到能够处理客户端的命令请求需要执行以下的步骤:

1、初始化服务器状态
2、载入服务器配置
3、初始化服务器的数据结构
4、还原数据库状态
5、执行事件循环
总的来说是这样子的:

def main:init_server;while server_is_not_shutdown;
aeProcessEventsclean_server;

http://chatgpt.dhexx.cn/article/c8uvlLfa.shtml

相关文章

Redis总结(八)redis单线程还是多线程问题

redis为什么可以支持高并发和它内部的工作模式有不可分割的关系: 绝大部分请求是纯粹的内存操作(非常快速)采用单线程,避免了不必要的上下文切换和竞争条件非阻塞IO - IO多路复用 Redis客户端对服务端的每次调用都经历了发送命令&#xff0…

redis单线程架构解析

简介 Redis使用单线程架构和I/0多路复用模型来实现高性能的内存数据库服务 单线程模型介绍 Redis单线程的优势 Redis是基于内存的,数据都存放在内存中,访问速度极快,这是Redis达到每秒万级别访问的重要基础非阻塞的I/O,Redis使…

详解redis单线程模型

背景:但凡你用redis都知道redis的一大特点就是单线程,那么在如今服务器普遍多核的时代下,为什么redis要采用单线程模型?单线程模型好在哪里?不用单线程模型redis是不是可以更快?带着这些问题我们一起来回顾…

2、Redis单线程高性能

Redis单线程,主要是指Redis的网络IO和键值对读写是由一个线程完成的。采用单线程的一个核心原因是避免多线程开发的并控制问题。 为什么这么快,Redis的大部分操作在内存中完成,再加上它高效的数据结构,这是它实现高性能的一个重要…

Redis单线程还是多线程?IO多路复用原理

目录 专栏导读一、Redis版本迭代二、Redis4.0之前为什么一直采用单线程?三、Redis6.0引入多线程四、Redis主线程和IO线程是如何完成请求的?1、服务端和客户端建立socket连接2、IO线程读取并解析请求3、主线程执行请求命令4、IO线程会写回socket和主线程清空全局队列五、IO多路…

Redis 单线程还是多线程?

Redis 单线程还是多线程 前段时间无意间看到一篇博客,讲述了Redis6即将在年底发布的事情,好奇心驱动下搜索了官网,想看看新版Redis带来了什么新的功能,果然得到证实Redis在年底将发布新的版本:6.0,并且Red…

redis单线程如何处理高并发的

这里写目录标题 1.IO(阻塞IO)和NIO(非阻塞IO)的概念2.redis的线程模型3.redis的通信协议 1.IO(阻塞IO)和NIO(非阻塞IO)的概念 1.jdk1.4引入了NIO,但也有很多人在用阻塞I…

为什么Redis单线程却比多线程快

为什么Redis单线程却比多线程快 redis三大特点为什么Redis是单线程单线程的优劣势题外 redis三大特点 1.Redis是基于内存,内存的读写是非常快的 2.Redis是单线程,省去了线程之间的切换并且防止了死锁现象发生 3.Redis采用多路复用的技术,可以…

Redis单线程模型

1、Redis单线程模型初步理解 针对每次请求调用,Redis都需经历接受命令、执行命令和返回结果三个过程。其中,执行命令阶段,因Redis是单线程处理命令,于是每一条到达redis服务端的命令不会立刻执行,而是所有命令都进入一…

3、redis 单线程 vs 多线程

1、Redis为什么选择单线程? 是什么 这种问法其实并不严谨,为啥这么说呢? Redis的版本很多3.x、4.x、6.x,版本不同架构也是不同的,不限定版本问是否单线程也不太严谨。 ①版本3.x ,最早版本,也就是大家…

Redis单线程原理

Redis单线程原理 Redis是单进程单线程的,Redis利用队列技术将并发访问变为串行访问,消除了传统数据库串行控制的开销。 单线程指的是网络请求模块使用了一个线程(所以不需考虑并发安全性),即一个线程处理所有网络请求…

【Redis】Redis单线程和多线程

Redis单线程 Redis为什么是单线程 Redis的版本很多,比如3.x、4.x、6.x等,版本不同,架构不同: 3.x版本,最早的版本,单线程4.x版本,严格意义上来说不是单线程,负责处理客户端请求的…

redis单线程模型阻塞问题浅析

redis知识速览 解决问题很好的一个方式就是先建立起“系统观”。这也就是说,如果我们想要深入理解和优化 Redis,就必须要对它的总体架构和关键模块有一个全局的认知,然后再深入到具体的技术点。 redis6.0之后就是多线程版本的了。 好久没写了…

Redis 单线程为什么速度这么快

总结了四点原因 1、基于内存,操作速度更快,每条命令的执行时间很短。 2、执行命令采用的是单线程操作,省去了线程切换的时空消耗。 3、采用了I/O多路复用,利用了epoll,提升了redis的I/O利用效率。 4、优秀的底层数…

redis单线程模式

1、redis单线程指的是:Redis 的网络 IO 和键值对读写是由一个线程来完成的,这也是 Redis 对外提供键值存储服务的主要流程。但 Redis 的其他功能,比如持久化、异步删除、集群数据同步等,其实是由额外的线程执行的。 **2、多线程开…

redis单线程

redis多线程6.0 redis单线程为什么快 单线程vs多线程 redis单线程指的是收到的读写命令是放到队列里,一条条执行的; redis用的io多路复用技术,所以可以一次性接收多个客户端请求,然后放到队列中; 先跟服务端建立连接…

Redis单线程和多线程

Redis单线程 Reids是单线程! Reids是单线程! Reids是单线程! Redis架构模型:Redis 基于 Reactor 模式来设计开发了自己的一套高效的事件处理模型 ,即文件事件处理器 文件事件处理器(file event handler) 主要是包含 4 个部分&…

Redis单线程模型详解

这里写目录标题 Redis 单线程模型简介文件事件常用的文件事件处理器客户端与Redis通信的一次流程 Redis为什么采用单线程模型Redis 为什么要引入多线程呢?为什么Redis单线程模型也能效率这么高? Redis 单线程模型简介 Redis 内部使用文件事件处理器 fil…

一文搞懂,redis单线程执行全貌(深入拆解分析)

文章目录 前言一、基础知识1.Reactor 单线程模型:2.文件描述符:3.套接字:4.服务端连接建立: 二、大话单线程模型1.建立连接:2.IO轮训及就绪事件处理3.命令处理及响应 三、总结 前言 本文参考源码版本为 redis6.2 redis…

高并发架构系列:Redis为什么是单线程、及高并发快的3大原因详解

Redis的高并发和快速原因 1.redis是基于内存的,内存的读写速度非常快; 2.redis是单线程的,省去了很多上下文切换线程的时间; 3.redis使用多路复用技术,可以处理并发的连接。非阻塞IO 内部实现采用epoll,采…