Redis到底是单线程还是多线程的?详解

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

Redis 的核心执行模型是单线程的,但自 Redis 6.0 版本起,在特定场景下支持了多线程处理。

1.1. Redis 的核心执行是单线程的

        Redis 的单线程指的是 Redis 的⽹络 IO 以及键值对指令读写是由⼀个线程来执⾏的。 对于

Redis 的持久化、集群数据同步、异步删除等都是其他线程执⾏。单线程保证了单条命令执行的有序性、原子性和一致性,同时避免了线程之间的切换所造成的资源开销,避免了线程之间的竞争问题,比如死锁等,不需要考虑各种锁问题。

        Redis的网络I/O是单线程指的是使用一个线程处理所有客户端连接的I/O,不管有多少客户端与Redis连接,所有的客户端请求(包括读写数据)都是通过Redis的这个单线程来处理的。

1.2. Redis中的多线程

        虽然 Redis来完成网络I/O和键值对读写操作是使用单线程的,但是因为单线程避免了线程切换之间的消耗、线程创建的开销等等,其执行效率在大多数场景下极高,但是随着网络I/O请求数量的急剧增加,当Redis服务器处于高负载情况时,单线程就无法高效的处理请求,因此自 Redis 6.0 开始,Redis引入了多线程网络I/O的功能,在高负载的情况下,Redis可以使用多线程来处理网络I/O,以减少网络I/O操作对性能的影响。

1.3. Redis多线程网络I/O的工作原理

        多线程网络I/O使用多个线程来并行处理客户端的请求接收和响应发送,但命令的执行仍然是单线程完成的。这意味着即使可以使用多个线程处理大量的并发网络请求,但对数据的实际读写仍然是单线程执行的

        Redis的多线程网络I/O底层工作原理是:I/O多路复用实现,多路是指多个socket连接,复用是指复用一个线程。多路复用主要有三种技术:select、poll、epoll,epoll是最新也是目前最好的多路复用技术。当多个客户端连接请求发送到服务器时,Redis会通过I/O多路复用机制来监听多个客户端连接的I/O事件(内核不是监视应用程序本身的连接,而是监视应用程序的文件描述符),然后Redis单线程会处理客户端的连接,并将这些连接交给多个I/O线程进行处理,I/O线程会并发的从不同客户端读取请求,并将请求缓存在一个队列中。每个I/O线程负责从客户端读取数据(例如SET或GET),并解析这些请求的内容。

        总结来说Redis的多线程是采用了 主线程 + 工作线程(I/O线程)模式,其中主线程负责核心的命令处理,只有一个核心线程, 它主要负责通过 I/O 多路复用机制 来监听多个客户端的连接,并处理命令的执行。 而工作线程(I/O线程)则负责网络I/O操作,解析具体的请求内容。

2. Redis是单线程的为什么还要使用分布式锁

        Redis中的单线程指的是Redis中的网络I/O和键值对的读写操作是由单线程完成的,它只保证了单线程中操作的有序性和原子性,也就是说对于每个客户端发来的请求,Redis会一个一个地处理,不会在命令执行过程中出现并发问题,但是在分布式系统的高并发场景下,Redis的单线程机制无法避免 多个客户端在同一时刻对同一个资源进行修改时可能出现的问题,也就是说Redis的单线程只能保证 每个命令 对Redis实例内部的顺序执行,无法控制客户端之间的请求顺序,因此就会导致多个客户端之间出现对公共变量的竞争问题。

        在分布式环境下,某些操作需要分成多个步骤进行,比如客户端需要先读取某共享变量的当前状态,然后基于该状态进行操作,最后更新该资源。这种情况下,如果多个客户端同时进行相同的操作,Redis无法保证这些操作之间的隔离性和有序性,会导致线程的不安全和数据的不一致。

举例:并发环境下的竞态示例

  • 线程A和B同时想操作同一个键key,假如它们都读取了key的初始值10,并且分别想把它加1。
  • 线程A读取了key的值为10,准备将其准备修改为11
  • 在A还没完成写入之前,B也读取了key的值为10,并准备将其修改为11.
  • 结果,A和B的写入操作最终导致key的值被设置为11,而不是12,因为B覆盖了A的结果。

        因此需要使用 分布式锁 来解决上述问题,它的作用是当多个线程尝试操作同一资源时,确保同一时刻只有一个线程能够获得资源的控制权,其他客户端必须等待该客户端释放锁后才能继续操作,确保了多个线程对共享资源的修改是有序的,避免了数据竞争和不一致的情况。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Unity实现自定义图集(四)

以下内容是根据Unity 2020.1.0f1版本进行编写的   在之前的篇章中已经把自定义图集在编辑器上的使用,以及运行时所需的信息都准备好了,接下来就是魔改UGUI的Image组件,使其能够像Image那样运行时如果引用的资源有打自定义图集,则加载对应自定义图集的Texture。 1、思路 …

【C语言】指针练习题

一、指针指向问题 int main() {int a[5] { 1, 2, 3, 4, 5 };int* ptr (int*)(&a 1);printf("%d,%d", *(a 1), *(ptr - 1));return 0; } 结果为:2,5。&a是整个数组(&a 1)被强转为(int*&am…

使用 Helsinki-NLP 中英文翻译本地部署 - python 实现

通过 Helsinki-NLP 本地部署中英文翻译功能。该开源模型性价比相对高,资源占用少,对于翻译要求不高的应用场景可以使用,比如单词,简单句式的中英文翻译。 该示例使用的模型下载地址:【免费】Helsinki-NLP中英文翻译本…

效率提高——自动登录校园网(河海大学)与模拟点击与输入获取最新消息

文章目录 零、前言一、自动登录校园网1.1 快速锁定小工具1.2 版本问题1.3 出现进程未结束的情况1.4 关于chromedriver.exe1.5 打包ico图片格式 二、获取信息门户最新消息参考文章 零、前言 最近被校园网弄的也是比较烦心,而且准备远程弄弄这些玩具,为以…

PostgreSQL数据库安全管理,细节都在这里了

📢📢📢📣📣📣 作者:IT邦德 中国DBA联盟(ACDU)成员,10余年DBA工作经验, Oracle、PostgreSQL ACE CSDN博客专家及B站知名UP主,全网粉丝10万 擅长主流Oracle、My…

创建一个c#程序,实现字符串类型转整数类型

首先,创建一个c#程序 在代码编辑器中编写代码,点击Run按钮或者按下F5键来运行程序。 下面,编写将字符串类型转换为整数类型的代码。 sing System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Task…

基于单片机的书库环境监测

目录 一、主要功能 二、硬件资源 三、程序编程 四、实现现象 一、主要功能 基于51单片机,采用DHT11湿度传感器检测湿度,DS18B20温度传感器检测温度, 采用滑动变阻器连接数模转换器模拟二氧化碳和氧气浓度检测,各项数值通过lc…

前端转换double数据,保留两位小数

Number Number(1.00) 1 Number(1.10) 1.1 Number(1.101) 1.101 要想前端展示页面按 1.00展示1,1.10 展示1.1 需要套一个number() 1.1 保留两位小数,并三位一个分隔符 indexView.value[key] formatNumber(indexView.value[key].toFixed(2))//格式…

五子棋项目自动化测试

目录 一、五子棋项目介绍 二、编写Web测试用例 三、自动化测试脚本开发 1、引入依赖 2、设计框架 3、Utils 4、LoginPage 5、RegisterPage 6、MatchPage 7、RunTest类 8、运行程序 一、五子棋项目介绍 五子棋项目是基于 WebSocket 实现的多人在线对战系统&#xff0…

【Vue】Vue 快速教程

Vue tutorial 参考:教程 | Vue.js (vuejs.org) 该教程需要前置知识:HTML, CSS, JavaScript 学习前置知识,你可以去 MDN Vue framework 是一个 JavaScript framework,以下简称 Vue,下面是它的特点 声明式渲染&#xff…

学习threejs,光晕效果

👨‍⚕️ 主页: gis分享者 👨‍⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍⚕️ 收录于专栏:threejs gis工程师 文章目录 一、🍀前言二、🍀光晕效果实现1. ☘…

powerbi之常用DAX函数使用介绍——提供数据源练习

前述: 本次使用数据是包含产品表、客户表、区域表、销售订单表的一份销售订单数据,数据源链接如下: 链接:https://pan.baidu.com/s/1micl_09hFrgz2aUBERkeZg 提取码:y17e 一、CALCULATE 1.语法结构 语法结构CALCUL…

使用Docker搭建WAF-开源Web防火墙VeryNginx

1、说明 VeryNginx 基于 lua_nginx_module(openrestry) 开发,实现了防火墙、访问统计和其他的一些功能。 集成在 Nginx 中运行,扩展了 Nginx 本身的功能,并提供了友好的 Web 交互界面。 文章目录 1、说明1.1、基本概述1.2、主要功能1.3、应用场景2、拉取镜像3、配置文件4、…

多线程——线程安全

目录 前言 一、观察线程不安全 二、线程安全概念 三、产生线程安全问题的原因 1.分析示例代码 2.线程随机调度 3.修改共享数据 4.原子性 5.可见性 6.指令重排序 四、解决示例代码的问题 结尾 前言 我们学习多线程编程的目的是为了能够实现“并发编程”,…

LSTM的变体

一、GRU 1、什么是GRU 门控循环单元(GRU)是一种循环神经网络(RNN)的变体,它通过引入门控机制来控制信息的流动,从而有效地解决了传统RNN中的梯度消失问题。GRU由Cho等人在2014年提出,它简化了…

C语言 | Leetcode C语言题解之第466题统计重复个数

题目&#xff1a; 题解&#xff1a; #include <stdlib.h> #include <stdio.h> #include <stdbool.h> #include <string.h> #include <math.h> #include <limits.h>#define MMAX(a, b) ((a) > (b)? (a) : (b)) #define MMIN(a,…

【项目】五子棋对战测试报告

目录 一、项目背景 二、项目功能 三、测试计划 1、功能测试&#xff1a; &#xff08;1&#xff09;测试用例&#xff1a; &#xff08;2&#xff09;实际执行测试的部分操作/截图 2、自动化测试 3、性能测试 一、项目背景 1、五子棋对战游戏 采用了前后端分离的方法来…

GO网络编程(七):海量用户通信系统5:分层架构

P323开始&#xff08;尚硅谷GO教程&#xff09;老韩又改目录结构了&#xff0c;没办法&#xff0c;和之前一样&#xff0c;先说下目录结构&#xff0c;再给代码&#xff0c;部分代码在之前讲过&#xff0c;还有知识的话由于本人近期很忙&#xff0c;所以这些就不多赘述了&#…

web自动化测试基础(从配置环境到自动化实现登录测试用例的执行,vscode如何导入自己的python包)

接下来的一段时间里我会和大家分享自动化测试相关的一些知识希望大家可以多多支持&#xff0c;一起进步。 一、环境的配置 前提安装好了python解释器并配好了环境&#xff0c;并安装好了VScode 下载的浏览器和浏览器驱动需要一样的版本号(只看大版本)。 1、安装浏览器 Chro…

vue-live2d看板娘集成方案设计使用教程

文章目录 前言v1.1.x版本&#xff1a;vue集成看板娘&#xff08;暂不使用&#xff0c;在v1.2.x已替换&#xff09;集成看板娘实现看板娘拖拽效果方案资源备份存储 当前最新调研&#xff1a;2024.10.2开源方案1&#xff1a;OhMyLive2D&#xff08;推荐&#xff09;开源方案2&…