Redis线程模型

article/2025/6/7 14:36:54

        前面的文章介绍了Redis的底层数据结构,这篇文章来介绍一下Redis的线程模型。

Redis为什么选择单线程?

        官方的回答是这样的,对于Redis来说,CPU通常不会成为瓶颈,因为大多数的请求不会是CPU密集型的,而是IO密集型的。如果不考虑RDB、AOF等信息持久化方案的话,Redis是完全纯内存操作,纯内存操作的执行速度是非常快的,所以这部分操作不会成为Redis的性能瓶颈。真正影响Redis性能的,是网络IO,也就是客户端和服务端之间的网络延迟造成的。因此Redis采用了单线程,在网络IO部分采用IO多路复用。

        更加具体的原因是在CPU不是性能瓶颈的前提下,相对于多线程模型,单线程模型避免了频繁上下文切换造成的开销,同时也不用考虑Redis众多底层数据结构的并发安全问题,这也使得Redis的底层相对简单好维护。总的来说,Redis采用单线程可以在保持高性能的同时,保持代码的简单可维护,毕竟多线程的理论和实际对比就可以很好的说明多线程在使用时的复杂与难以维护:

Redis为什么又引入了多线程?

        Redis其实在v4.0时就引入了多线程,主要用来异步处理一些比较耗时的任务,避免核心线程被长时间阻塞;v6.0时引入了多线程IO,主要用来处理网络数据的读写和协议内容的解析。多线程IO的引入主要是由于互联网的飞速发展,互联网业务需要处理的线上流量越来越大,Redis的单线程模式会导致相当一部分CPU时间消耗在网络IO上,而导致Redis整体的吞吐量降低。如果要对Redis性能进行优化,可以从两方面来入手:①优化网络IO模块、②提高机器内存的读写速度。

        第②种依赖于硬件的突破,所以只能从第一种方法入手,第一种方法又可以细分为两个方向:①零拷贝技术或者DPDK技术、②利用多核CPU优势。

        零拷贝技术有自身的局限性,无法完全适配Redis这一类复杂的网络IO场景。DPDK技术通过旁路网卡IO绕过内核协议的方式又太过于复杂以及需要内核的支持。所以最终选择的就是利用多核CPU的优势,通过使用多线程将网络IO任务进行分摊。

        Redis6.0在引入多线程IO后,在4线程IO时,GET/SET的性能相较于单线程几乎翻倍。

Redis的线程模型

        Redis的线程模型分为v6.0之前和v6.0之后两个版本。

v6.0之前:

        采用基于Recator模式的网络事件处理器。这个处理器被称为文件事件处理器。它的组成结构为4部分,多个Socket、IO多路复用程序、文件事件分派器和事件处理器。因为文件事件分派器队列和消费是单线程的,所以说Redis是单线程模型。Redis6.0之前的线程模型如下图所示:

        多个Socket:Socket会产生AE_READABLE和AE_WRITABLE事件。当Socket变得可读或者有新的可以应答的Socket出现时,就会产生一个AE_READABLE事件;当Socket变得可写时,就会产生一个AE_WRITABLE事件。

        IO多路复用程序:IO多路复用的实现有select、poll和epoll三种技术,其中epoll是性能最好的。

        事件处理器:事件处理器包括连接应答处理器、命令请求处理器和命令回复处理器。如果是客户端请求连接Redis,那么会为Socket关联连接应答处理器;如果是客户端要写数据到Redis,那么会为Socket关联命令请求处理器;如果是客户端要从Redis读数据,那么会为Socket关联命令回复处理器。

        多个Socket会产生不同的事件,不同的事件对应着不同的操作,IO多路复用程序监听着这些Socket,当这些Socket产生了事件,IO多路复用程序会将这些事件放到一个队列中,通过这个队列,以有序、同步、每次一个事件的方式向文件事件分派器中传送。当事件处理器处理完一个事件后,IO多路复用程序才会继续向文件分派处理器传送下一个事件。

        Redisv6.0线程模型下,客户端与Redis一次完整的通信流程如下:

        ①Redis启动初始化时,Redis会将连接应答处理器与AE_READABLE事件关联起来。

        ②一个客户端发起与Redis的连接请求,此时Redis产生一个AE_READABLE事件,此时连接应答处理器来处理此事件,连接应答处理器与客户端建立连接,创建客户端相应的Socket,同时将这个Socket的AE_READABLE事件与命令请求处理器关联。

        ③这个客户端向Redis发送了一条命令,相应的Socket产生一个AE_READABLE事件,IO多路复用程序将事件压入队列中。事件分配处理器拿到该事件,将该事件分配给命令请求处理器处理,命令请求处理器读取事件中的命令并完成。完成后将Socket的AE_WRITABLE事件与命令回复处理器相关联。

        ④如果客户端已经准备好接收数据,相应Socket会产生一个AE_WRITABLE事件,同时会压入队列中然后被事件分配处理器分配给命令回复处理器,由其将准备好的响应数据写入Socket给客户端读取。

        ⑤命令回复处理器写完后,就会删除该Socket的AE_WRITABLE事件与命令请求处理器的关联关系。

v6.0之后:

        v6.0之后的流程与v6.0之前的最大区别在于网络数据的读写部分。

        Redis的主线程负责接受连接建立请求,获取Socket并将其放入全局等待读处理队列;主线程处理完读事件后,通过Round Robin将这些链接分配给IO线程;主线程阻塞等待IO线程读取Socket完成;主线程通过单线程的方式执行请求命令,并将数据写入缓冲区;主线程阻塞等待IO线程将数据写回给Socket。具体流程如下图所示:

        可以看到,Redis的多线程只体现在Socket命令的读取和写回,而命令的执行还是主线程在单线程执行,所以说Redis的核心仍然是单线程的,不用考虑并发安全的问题。

        到此Redis的线程模型就介绍完毕啦,大家有什么问题或者勘误可以在评论区留言,笔者看到都会回复的。

        


http://www.hkcw.cn/article/PfFugXDLCE.shtml

相关文章

工厂方法模式深度解析:从原理到应用实战

作者简介 我是摘星,一名全栈开发者,专注 Java后端开发、AI工程化 与 云计算架构 领域,擅长Python技术栈。热衷于探索前沿技术,包括大模型应用、云原生解决方案及自动化工具开发。日常深耕技术实践,乐于分享实战经验与…

STM32入门教程——按键控制LED光敏传感器控制蜂鸣器

前言 本教材基于B站江协科技课程整理,适合有C语言基础、刚接触STM32的新手。它梳理了STM32核心知识点,帮助大家把C语言知识应用到STM32开发中,更高效地开启STM32学习之旅。 目录 前言 一、硬件接线与模块化编程概述 二、LED 驱动模块开发…

K8s基础一

Kubernetes 架构 Kubernetes 背后的架构概念。 Kubernetes 集群由一个控制平面和一组用于运行容器化应用的工作机器组成, 这些工作机器称作节点(Node)。每个集群至少需要一个工作节点来运行 Pod。 工作节点托管着组成应用负载的 Pod。控制平…

Spring @Value注解的依赖注入实现原理

Spring Value注解的依赖注入实现原理 一,什么是Value注解的依赖注入二,实现原理三,代码实现1. 定义 Value 注解2. 实现 InstantiationAwareBeanPostProcessor3. 实现 AutowiredAnnotationBeanPostProcessor4. 占位符解析逻辑5. 定义 StringVa…

Oracle、PostgreSQL 与 MySQL 数据库对比分析与实践指南

一、三大数据库基础认知 Oracle数据库 基本概况 ✔ 厂商:Oracle Corporation ✔ 许可证:商业授权(含Oracle XE免费版本) ✔ 典型用户:大型银行、政府机构、电信运营商 核心特性 -- 示例:Oracle PL/SQL存…

protobuf arena实现概述

Arena是Protobuf的C特有特性,旨在优化内存分配效率,减少频繁的堆内存申请与释放。其核心机制如下: 预分配内存:Arena预先分配一大块连续内存(称为Block),对象创建时直接从该内存块中分配&#x…

深入浅出图神经网络:从核心概念到实战落地

文章目录 1 引言1.1 发展脉络与现状1.2 面临挑战1.3 本文目标 2 图结构数据基础2.1 关键元素2.2 数学定义与常用符号2.3 图的常见类型2.4 为什么这些定义重要? 3 GNN 核心思想:消息传递机制3.1 消息函数 M E S S A G E ( k ) \mathrm{MESSAGE}^{(k)} ME…

6级阅读学习

先找连接词,and什么的 再找that什么的 最后找介词短语

当 AI 超越人类:从技术突破到文明拐点的 2025-2030 年全景展望

引言:当科幻照进现实的十年 2025 年的某个清晨,当你对着智能音箱说出 “帮我订一份早餐” 时,或许不会想到,这个简单指令背后的技术演进,正悄然推动人类文明走向一个前所未有的拐点。从弱人工智能(ANI)到强人工智能(AGI)的跃迁,不再是科幻小说的专属设定,而是现实世…

安全-JAVA开发-第一天

目标: 安装环境 了解基础架构 了解代码执行顺序 与数据库进行连接 准备: 安装 下载IDEA并下载tomcat(后续出教程) 之后新建项目 注意点如下 1.应用程序服务器选择Web开发 2.新建Tomcat的服务器配置文件 并使用 Hello…

Spring @Autowired自动装配的实现机制

Spring Autowired自动装配的实现机制 Autowired 注解实现原理详解一、Autowired 注解定义二、Qualifier 注解辅助指定 Bean 名称三、BeanFactory:按类型获取 Bean四、注入逻辑实现五、小结 源码见:mini-spring Autowired 注解实现原理详解 Autowired 的…

【AI News | 20250603】每日AI进展

AI Repos 1、dgm 是一个创新的自改进系统,通过迭代修改自身代码并利用编码基准验证每次更改,实现开放式进化。该系统旨在提升 AI 代理的代码修改能力。DGM 支持 OpenAI 和 Anthropic API,依赖 Docker 环境,并集成了 SWE-bench 和…

Rust 学习笔记:Cargo 工作区

Rust 学习笔记:Cargo 工作区 Rust 学习笔记:Cargo 工作区创建工作区在工作区中创建第二个包依赖于工作区中的外部包向工作区添加测试将工作区中的 crate 发布到 crates.io添加 add_two crate 到工作区总结 Rust 学习笔记:Cargo 工作区 随着项…

操作系统 第 39 章 插叙:文件和目录

两项关键操作系统技术的发展:进程,虚拟化的 CPU;地址空间,虚拟化的内存。 这一部分加上虚拟化拼图中最关键的一块:持久存储。永久存储设备永久地(或至少长时间地)存储信息,如传统硬盘…

楼宇自控系统联动暖通空调:解密建筑环境舒适度提升路径

走进现代建筑,无论是办公场所、商业中心,还是医院、酒店,人们对环境舒适度的要求越来越高。暖通空调作为调节建筑室内环境的关键设备,其运行效果直接影响着人们的体验。然而,传统暖通空调独立运行、调控不灵活等问题&a…

Freemarker快速入门

Freemarker概述 FreeMarker 是一款 模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页,电子邮件,配置文件,源代码等)的通用工具。 它不是面向最终用户的,而是一个Java类库&#xff0c…

黑盒(功能)测试基本方法

🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快 一、黑盒测试的概念 1、什么是黑盒测试 (1)黑盒测试又称功能测试、数据驱动测试或基于规格说明书的测试,是一种从用户观点出…

[java八股文][JavaSpring面试篇]SpringCloud

了解SpringCloud吗,说一下他和SpringBoot的区别 Spring Boot是用于构建单个Spring应用的框架,而Spring Cloud则是用于构建分布式系统中的微服务架构的工具,Spring Cloud提供了服务注册与发现、负载均衡、断路器、网关等功能。 两者可以结合…

chromedriver 下载失败

问题描述 chromedriver 2.46.0 下载失败 淘宝https://registry.npmmirror.com/chromedriver/2.46/chromedriver_win32.zip无法下载 解决方法 找到可下载源 https://cdn.npmmirror.com/binaries/chromedriver/2.46/chromedriver_win32.zip ,先将其下载到本地目录(D…

74. 搜索二维矩阵 (力扣)

给你一个满足下述两条属性的 m x n 整数矩阵: 每行中的整数从左到右按非严格递增顺序排列。每行的第一个整数大于前一行的最后一个整数。 给你一个整数 target ,如果 target 在矩阵中,返回 true ;否则,返回 false 。…