【Redis】Redis线程模型

目录

    • 1. Redis 是单线程的,还是多线程的?
    • 2. Redis单线程模式是怎么样的?
      • Redis 单线程模式的优势
      • Redis 单线程的局限性
      • Redis 单线程的优化策略
    • 3. Redis采用单线程为什么还这么快
    • 4. Redis 6.0 之前为什么使用单线程?
    • 5. Redis 6.0 之后为何引入多线程?

1. Redis 是单线程的,还是多线程的?

Redis 的主要操作是单线程的,这意味着它在主线程上处理所有请求,而不像一些数据库采用多线程模型。这是因为 Redis 的开发者追求的是简化并发操作、避免线程锁机制带来的复杂性和性能开销。通过单线程模型,Redis 避免了常见的线程切换、死锁等问题,大大提升了效率。

Redis 单线程指的是「接收客户端清求->解析请求 ->进行数据读写等操作->发送数据给客户端」这个过
程是由一个线程(主线程)来完成的,这也是我们常说 Redis 是单线程的原因。对于读写命令来说,Redis 一直是单线程模型。不过,在 Redis 4.0 版本之后引入了多线程来执行一些大键值对的异步删除操作, Redis6.0版本之后引入了多线程来处理网络请求(提高网络 I0 读写性能)

但是,Redis 程序并不是仅仅是单线程的,Redis 在启动的时候,是会启动后台线程(BIO)的:

  • Redis 在 2.6 版本,会启动2个后台线程,分别处理关闭文件、AOF 刷盘这两个任务;
  • Redis 在 4.0 版本之后,新增了一个新的后台线程,用来异步释放 Redis 内存,也就是 lazyfree 线程。例如执行 unlink key/flushdb async/flushall async 等命令,会把这些删除操作交给后台线程来执行好处是不会导致 Redis 主线程卡顿。因此,当我们要删除一个大 key 的时候,不要使用 del 命令删除因为 del是在主线程处理的,这样会导致 Redis 主线程卡顿,因此我们应该使用 unlink 命令来异步删除大key

之所以 Redis 为「关闭文件、AOF 刷盘、释放内存」这些任务创建单独的线程来处理,是因为这些任务的操作都是很耗时的,如果把这些任务都放在主线程来处理,那么 Redis 主线程就很容易发生阻塞,这样就无法处理后续的请求了。
在这里插入图片描述

后台线程相当于一个消费者,生产者把耗时任务丢到任务队列中,消费者(BIO)不停轮询这个队列,拿出任务就去执行对应的方法即可。

2. Redis单线程模式是怎么样的?

Redis6.0版本之前的单线程模式如下图:(图片来源小林coding)
在这里插入图片描述在 Redis 6.0 版本之前,Redis 的处理模型完全是 单线程 的,所有操作都在一个线程中完成。这种单线程模式虽然看似简单,但由于 Redis 的设计精巧,结合了高效的内存操作和 I/O 多路复用机制,它依然能够在很多场景下表现出色。

Redis 使用 I/O 多路复用机制 来处理并发客户端连接。在这种机制下,一个线程可以同时监听多个文件描述符(即客户端连接)。当某个文件描述符有事件发生(如客户端发送了命令或等待处理的请求到来),Redis 会处理这些事件,而不是为每个连接创建一个独立的线程。

具体的步骤如下:

1. 事件监听:Redis 的主线程通过 I/O 多路复用(如 epoll、select 等系统调用)监听多个客户端连接。当某个连接有新的请求到来时,Redis 会记录这个事件。
2. 事件处理:当有多个客户端的事件需要处理时,Redis 按照队列的顺序处理每个请求。这意味着 Redis 通过单线程的轮询方式来处理每一个客户端请求。
3. 命令执行:Redis 按顺序处理请求,包括读取命令、执行命令、返回结果等所有操作都在主线程中完成。

Redis 单线程模式的优势

  1. 避免复杂的线程同步问题

Redis 采用单线程设计的一个主要原因是避免了多线程中的复杂同步问题。在多线程环境下,多个线程对共享资源的并发访问需要使用锁机制来保护数据的完整性,但这也会带来性能开销。单线程的 Redis 不需要考虑加锁问题,因为所有的请求都是在同一个线程中按顺序执行,天然避免了竞争条件(race conditions)、死锁和其他并发问题。

  1. 高效的内存操作

Redis 是一个基于内存的数据库,大部分数据操作都是直接在内存中进行的。内存操作的速度非常快,通常在微秒级别。这使得即使 Redis 是单线程的,它在处理绝大多数简单的读写请求时也能够表现得非常高效。

  1. I/O 多路复用

Redis 使用 I/O 多路复用(如 epoll)来处理大量并发连接。I/O 多路复用允许一个线程同时监控多个客户端连接的输入输出,而不会阻塞在某个连接上。这意味着,虽然 Redis 是单线程,但它依然可以高效地处理成千上万的并发连接。

非阻塞 I/O:Redis 的网络操作是非阻塞的,这意味着即便某个连接上没有立即准备好数据,Redis 也不会停下来等待,而是继续处理其他连接上的请求。事件驱动模型:Redis 使用事件驱动模型来处理网络 I/O,即当某个连接上有新的事件(如数据可读、可写等)时,Redis 会立即响应并处理这个事件。这样,Redis 不需要为每个连接分配单独的线程,而是通过事件驱动的方式让单线程高效运作。

Redis 单线程的局限性

虽然 Redis 单线程模式在大多数场景下表现良好,但也存在一些局限性,特别是在特定条件下可能成为瓶颈:

  1. CPU 密集型任务

虽然 Redis 的大部分操作都是非常轻量的,但在某些 CPU 密集型任务中,如处理非常大的集合或执行复杂的 Lua 脚本,单线程的性能可能会不足。当 Redis 需要在主线程中执行耗时较长的计算时,其他客户端的请求可能会因此被阻塞。

  1. 大数据量的磁盘 I/O

当 Redis 执行持久化操作时(如将数据写入 AOF 文件或 RDB 文件),写入磁盘是一个相对慢的操作。虽然 Redis 通过异步机制和后台线程来优化某些持久化任务(如 AOF 重写和 RDB 文件生成),但在 6.0 之前版本中,网络 I/O 和命令处理仍然完全依赖主线程,因此在高并发场景下,磁盘 I/O 可能成为性能瓶颈。

  1. 处理大型数据集的阻塞问题

对于像删除大量数据(如一个包含数百万个元素的哈希或列表)或从主线程直接进行内存清理这样的操作,单线程可能会导致 Redis 短暂阻塞,影响其他请求的处理。为此,Redis 提供了 UNLINK 等命令来将大型对象的删除任务交由后台线程异步处理,减少主线程的负载。

Redis 单线程的优化策略

为了解决单线程的性能瓶颈,Redis 在 6.0 之前引入了一些优化策略:

异步删除:通过命令 UNLINK 和 FLUSHALL/FLUSHDB ASYNC,Redis 能够将大数据块的删除操作交由后台线程异步执行,从而避免删除大对象时主线程的阻塞。Lazy-Free 机制:Redis 提供了“惰性删除”机制,允许用户在删除大对象时,分步释放对象占用的内存,而不是一次性完成,从而减小对主线程的影响。后台持久化:对于 RDB 生成和 AOF 重写操作,Redis 通过后台子进程完成。这些操作涉及到磁盘 I/O,通常比较耗时,但通过子进程执行,避免了主线程的阻塞。

总结:

Redis 6.0 版本之前的单线程模式基于 I/O 多路复用和事件驱动模型,能够高效处理大量并发请求。它的优点在于实现简单、避免复杂的并发问题,同时依赖内存操作和非阻塞 I/O,保证了大多数场景下的高性能表现。

然而,在 CPU 密集型任务、大数据集操作和磁盘 I/O 瓶颈等场景下,单线程模式可能会遇到一些性能瓶颈。因此,在 Redis 6.0版本中,引入了多线程来优化网络 I/O 的处理能力,从而进一步提升 Redis 在高并发场景下的性能表现。

3. Redis采用单线程为什么还这么快

官方使用基准测试的结果是,单线程的 Redis 吞吐量可以达到 10W/每秒,如下图所示:

在这里插入图片描述Redis 采用单线程(处理网络 I/O 和执行命令)却依然能够保持极高的性能,主要有以下几个原因:

  1. 基于内存的操作

Redis 是一个 内存数据库,所有数据操作都直接在内存中完成。相比传统的磁盘数据库,内存读写速度极快,通常在微秒级别。这使得 Redis 能够非常迅速地处理请求,减少了 I/O 等待时间。

  1. I/O 多路复用机制

Redis 使用 I/O 多路复用(如 epoll、kqueue 或 select)来同时处理多个客户端连接。尽管 Redis 是单线程的,但它能够高效地处理大量并发连接,因为它不需要为每个连接创建单独的线程或进程,而是通过事件驱动的方式监听和处理多个连接上的请求。多路复用允许 Redis 处理大量并发请求的能力远超一般的单线程程序。

  1. 非阻塞 I/O

Redis 采用 非阻塞 I/O 模式,主线程不会因为某个 I/O 操作(如等待客户端请求数据或写入响应)而被卡住。即使某个客户端数据没有完全到达,Redis 也不会阻塞,而是先处理其他已经准备好的请求,保证主线程的连续执行和高效处理。

  1. 单线程避免了锁的开销

多线程编程通常需要处理线程之间的同步问题,比如加锁、解锁等操作,这些都会引入性能开销。Redis 的单线程模型完全避免了这些复杂性,因为所有的操作都是按顺序执行的,不需要使用锁来保证数据一致性。因此,Redis 能够避免常见的多线程编程中的资源竞争、锁定和上下文切换带来的性能损失。

  1. 简单高效的事件驱动模型

Redis 的事件驱动模型设计简洁,主线程通过事件循环不断监听并处理新的客户端连接、请求和响应。这种模型非常轻量化,减少了上下文切换和系统调用的开销,使得 Redis 在处理大量连接时依然保持高效。

  1. 高效的数据结构

Redis 的数据结构设计非常高效,它在内存中使用了优化的编码方式(如 ziplist、intset 等)来存储数据。这些数据结构专为快速访问和操作而设计,使得 Redis 可以在单线程模式下快速执行各种数据操作。

4. Redis 6.0 之前为什么使用单线程?

虽然说 Redis 是单线程模型,但实际上,Redis 在 4.0 之后的版本中就已经加入了对多线程的支持。不过,Redis 4.0增加的多线程主要是针对一些大键值对的删除操作的命令,使用这些命令就会使用主线程之外的其他线程来“异步处理”,从而减少对主线程的影响。

Redis官方的F&Q
在这里插入图片描述在这里插入图片描述
使用单线程的原因:

  • 单线程编程容易并且更容易维护;
  • Redis的性能瓶颈不在 CPU,主要在内存和网络IO;
  • 多线程就会存在死锁、线程上下文切换等问题,甚至会影响性能。

5. Redis 6.0 之后为何引入多线程?

虽然 Redis 的主要工作(网络 I/O和执行命令)一直是单线程模型,但是在 Redis 6.0 版本之后,也采用多个IO线程来处理网络请求,这是因为随着网络硬件的性能提升,Redis 的性能瓶颈有时会出现在网络 I/O 的处理上

所以为了提高网络 I/O 的并行度,Redis 6.0 对于网络 I/O 采用多线程来处理。但是对于命令的执行,Redis 仍然使用单线程来处理,所以不要误解 Redis 有多线程同时执行命令。

Redis 6.0 版本支持的 I/O 多线程特性,默认情况下 I/O 多线程只针对发送响应数据(write client socket),并不会以多线程的方式处理读请求(read client socket)。要想开启多线程处理客户端读请求,就需要把 Redis.conf 配置文件中的 io-threads-do-reads 配置项设为 yes。

//读请求也使用io多线程
io-threads-do-reads yes 

同时, Redis.conf 配置文件中提供了IO 多线程个数的配置项。

// io-threads ,表示启用 N-1 个 I/0 多线程(主线程也算一个 I/0 线程)
io-threads 4

关于线程数的设置,官方的建议是如果为4核的 CPU,建议线程数设置为2 或 3,如果为8核 CPU 建议线程数设置为 6,线程数一定要小于机器核数,线程数并不是越大越好。

因此, Redis 6.0 版本之后,Redis 在启动的时候,默认情况下会额外创建6个线程(这里的线程数不包括主线程)

  • Redis-server:Redis的主线程,主要负责执行命令;
  • bio_close_file、bio_aof_fsync、bio_lazy_free:三个后台线程,分别异步处理关闭文件任务、AOF刷盘任务、释放内存任务;
  • io_ thd_1、io_thd_2、io_thd_3:三个I/O 线程,io-threads 默认是4,所以会启动3(4-1)个I/O多线程,用来分担 Redis 网络I/O 的压力。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/442759.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

10.1 10.3 图DFS 中等 207 Course Schedule 210 Course Schedule Ⅱ

207 Course Schedule class Solution { public:bool hasCycle(int course ,unordered_map<int,vector<int>>& graph,vector<int>& visitStatus){//正在访问的结点再次被访问&#xff0c;存在环if(visitStatus[course] 1)return true;//该结点已经被…

仪器校准机构提供了资质证明,就能够代表目前的检测能力吗?

最近的一次公司审核打破了我对仪器校准机构能力认证这一独特理论的认识。换句话说&#xff0c;最近参加了公司的质量整合审核&#xff0c;其中之一就是仪器校准机构检测能力审核。根据我平时的经验&#xff0c;我给审核老师提供了CNAS和客户等一系列资质证书&#xff0c;以证明…

PMP--冲刺题--解题--91-100

文章目录 11.风险管理--4.实施定量风险分析--题干场景中提到了“专家”&#xff0c;同时即将开始“量化风险”&#xff0c;因此对应的就是“定量风险分析”中的“专家判断”技术。项目经理应先征求各位专家们的意见&#xff0c;以获取最佳的量化风险实施方案。谋定而后动91、 […

芯片复位电路-RC复位

芯片复位电路-RC复位 MAX809专门的上电复位芯片使用注意芯片间级联复位 看门狗复位注意事项 MAX809专门的上电复位芯片 可以看到这里VTH这个电压值一般是你你电复位芯片供电的90%左右&#xff0c;比如说5V&#xff0c;那这里可能是4.5V。 使用注意 A.复位输出引脚要加上拉电阻…

解决跨域问题

第一种 让后端解决 第二种 通过代理来解决 首先可以先搭建后端接口 解决则参照vue-cli官网 首先新建一个vue.config.js文件 然后在项目的根目录新建两个文件夹 开发环境和生产环境 然后可以使用环境变量 系统会自动识别你是生产环境还是开发环境 然后在封装的axios中配…

【Qt】控件概述 (1)—— Widget属性

控件概述 1. QWidget核心属性1.1核心属性概述1.2 enable1.3 geometry——窗口坐标1.4 window frame的影响1.4 windowTitle——窗口标题1.5 windowIcon——窗口图标1.6 windowOpacity——透明度设置1.7 cursor——光标设置1.8 font——字体设置1.9 toolTip——鼠标悬停提示设置1…

Puppeteer自动化:使用JavaScript定制PDF下载

引言 在现代的Web开发中&#xff0c;自动化已经成为提高效率和减少重复劳动的重要手段。Puppeteer 是一个强大的Node.js库&#xff0c;提供了对无头Chrome或Chromium的控制&#xff0c;可以用于生成网页快照、抓取数据、自动化测试等任务。其中&#xff0c;生成PDF文件是一个常…

cnn突破八(两层卷积核bpnet网络扩展)

cnn突破七中x【&#xff1f;】怎么求&#xff1f;我们举个例子&#xff1a; 接着cnn突破七&#xff1a; hicnn【】来自temphicnn【】2*2最大池化&#xff1a; temphicnn[0]x[i0,j0,5*5方阵]*w1cnn[0-24]&#xff0c; hicnn是5*5的&#xff0c;temphicnn是10*10的&#xff0…

git clone 私有仓库时出现错误 Authentication failed for :xxxxxx

错误信息 remote: Support for password authentication was removed on August 13, 2021. remote: Please see https://docs.github.com/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended…

音频剪辑在线工具 —— 让声音更精彩

你是否曾梦想过拥有自己的声音创作空间&#xff0c;却苦于复杂的音频编辑软件&#xff1f;接下来&#xff0c;让我们一同揭开这些音频剪辑在线工具的神秘面纱&#xff0c;看看它们如何帮助你实现从录音到发布的无缝衔接。 1.福昕音频剪辑 链接直达>>https://www.foxits…

Windows系统编程(三)线程并发

进程与线程 进程&#xff1a;直观的说就是任务管理器中各种正在运行的程序。对于操作系统来说&#xff0c;进程仅仅是一个数据结构&#xff0c;并不会真实的执行代码 线程&#xff1a;通常被称作但并不真的是轻量级进程或实际工作中的进程&#xff0c;它会真实的执行代码。每…

Qwen变体新成员加一,英伟达训练 NVLM-D-72B 视觉大模型

今天&#xff08;2024 年 9 月 17 日&#xff09;&#xff0c;我们推出了前沿级多模态大语言模型&#xff08;LLM&#xff09;系列 NVLM 1.0&#xff0c;它在视觉语言任务上取得了最先进的结果&#xff0c;可与领先的专有模型&#xff08;如 GPT-4o&#xff09;和开放存取模型&…

易图讯军用VR三维电子沙盘系统

深圳易图讯军用VR三维电子沙盘系统是一种集成了虚拟现实&#xff08;VR&#xff09;技术、三维建模技术、大数据分析、实时动态更新以及高度安全可靠的综合性军事指挥平台。该系统通过高精度三维模型真实再现战场环境&#xff0c;为指挥员提供沉浸式体验和交互操作的可能性&…

【黑马点评】0.环境配置--Redis6.2.6和可视化工具在Windows上的安装

黑马点评--0.Redis6.2.6在windows上的环境配置与可视化 0 前言1 下载安装2 解压后运行msi文件3 修改配置文件并打开Redis3.1 修改密码&#xff08;可选&#xff09;3.2 测试 4 Redis可视化&#xff08;可选&#xff09;4.1 Another Redis Desktop Manager下载安装4.2 连接Redis…

N1从安卓盒子刷成armbian

Release Armbian_noble_save_2024.10 ophub/amlogic-s9xxx-armbian (github.com) armbian下载&#xff0c;这里要选择905d adb 下载地址 https://dl.google.com/android/repository/platform-tools-latest-windows.zip 提示信息 恩山无线论坛 使用usb image tool restet a…

深入理解NumPy库:常用函数详解与数组操作指南

在数据科学和数值计算领域&#xff0c;NumPy无疑是一个强大的工具&#xff0c;它为Python提供了高效的多维数 组处理能力。无论是进行数据分析、构建机器学习模型&#xff0c;还是进行复杂的科学计算&#xff0c;NumPy都是 不可或缺的核心库之一。 numpy.array 是 NumPy 库中…

C# 获取可执行文件目录

---------------------------------------------------------------------------

SpringMVC框架:入门讲解和基础案例解析

Spring Web MVC是什么&#xff1f; Spring Web MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架。使用了MVC架构模式的思想&#xff0c;将web层进行职责解耦&#xff0c;基于请求驱动指的就是使用请求-响应模型 。框架的目的就是帮助我们简化开发&…

PCB板材基本知识

术语 名称定义插图 copper foil 铜箔 Copper Clad Laminates&#xff0c;CCL 覆铜箔层压板 CCL是PCB制造的上游核心材料&#xff0c;是将电子玻纤布或其它增强材料浸以树脂&#xff0c;一面或双面覆以铜箔并经热压而制成的一种板状材料&#xff0c;担负着&#xff08;PCB&am…

优先级队列详解

一&#xff0c;优先级队列 什么是优先级队列呢&#xff0c;不知道大家了解过队列没有&#xff0c;队列是一种先进先出的数据结构&#xff0c;但是我们有时会想让优先级高的先出队列&#xff0c;所以我们出现了一种新的数据结构&#xff0c;我们实现两种主要功能得到优先级高的数…