Redis的单线程与多线程

Redis的核心处理逻辑一直都是单线程 有一些分支模块是多线程(某些异步流程从4.0开始用的多线程,例如UNLINK、FLUSHALL ASYNC、FLUSHDB ASYNC等非阻塞的删除操作。网络I/O解包从6.0开始用的是多线程;)

为什么是单线程

多线程多好啊可以利用多核优势

官方给的解释

意思就是Redis的定位,是内存k-v存储, 是做短平快的热点数据处理,一般来说执行会很快,执行本身不是瓶颈,而瓶颈通常在网络I/O,处理逻辑多线程并不会有太大收益。
同时,Redis本身 秉持简洁高效的理念,代码的简单性、可维护性 是Redis以来一直以来的追求,引入多线程带来的复杂性远比想象的要大,而且多线程本身也会引入额外成本,细说

1.多线程的引入的复杂度很大


1.首先,多线程引入之后,Redis原来的顺序执行特性就不复存在,为了支持事务的原子性、隔离性,Redis就不得不引入一些很复杂的实现; .
2.Redis的数据结构极其高效,在单线程模式下做了很多特性的优化,如果引入多线程,那么所有
底层数据结构都要改造为线程安全,这会是极其复杂的工作;
3.而且,多线程模式也使得程序调试更加复杂和麻烦,会带来额外的开发成本及运营成本,也更容易犯错(回想一下MYSQL并发....)

2.多线程带来额外的成本

1.上下文切换成本,多线程调度需要切换线程上下文,这个操作先存储当前线程的本地数据、程序指针等,然后载入另一个线程数据,这种内核操作的成本不可忽视。
2.同步机制的开销,-些公共资源,在单线程模式下直接访问就行了,多线程需要通过加锁等方式去进行同步,这也是不可忽视的CPU开销;
3.一个线程本身也占据内存大小,对Redis这种内存数据库而言,内存非常珍贵,多线程本身带来的内存使用的成本也需要谨慎决策。
 

单线程为什么这么快

第一,Redis的大部分操作在内存上完成,内存操作本身就特别快;
第二,Redis追求极致,选择了很多高效的数据结构,并做了非常多的优化,比如ziplist, hash,跳表,有时候一种对象底层有几种实现以应对不同场景。
第三,Redis 采用了多路复用机制,使其在网络I0操作中能并发处理大量的客户端请求,实现高吞吐量。
第一第二点挺好理解的 第三点怎么说

什么叫I/0多路复用,简单理解来说,就是有I/0操作触发的时候,就会产生通知,收到通知,再去处理通知对应的事件,针对I/0多路复用,Redis做了一层包装,叫Reactor模型。
本质就是监听各种事件,当事件发生时,将事件分发给不同的处理器。

这样就不会阻塞在某一个操作上,充分发挥性能,可以说I/O多路复用让Redis单线程也有了较大的并发度,注意这里是并发,而不是并行,在这种模式下,Redis单 核的性能可以说是被充分的利用了。
 

但是呢

现在业务量实在是太大了

前面也有说过,Redis选择 单线程的核心原因是Redis是都是内存操作,CPU处理都非常快,瓶颈更容易出现在I/O而不是CPU,所以选择了单线程模型。

随着时代的发展,很多业务的请求量都达到了一个曾经难以想象的高度,I/O操作确实成为了瓶颈,而之前Redis处理流程中读取请求、发送回包都属于I/O操作,所以Redis引入了多线程,这里的多线程也不是说将整个处理逻辑都多线程化,如果这么做,需要对所有数据结构进行线程安全重构,这是巨大的成本,并且,也不见得能有多大提升,甚至可能因为损耗而降低,毕竟瓶颈大多时候都不在处理,瓶颈实际一般都在 于网络I/O。
因为上述情况,Redis选择了引入多线程来处理网络I/O,仍然使用单线程框架来执行Redis命令,这样既保持了Redis核心的单线程处理架构,完全兼容以前的实现,又引入了多线程解决提升网络I/O的性能。
 

关于多线程不需要了解太多

首先 多线程是6.0之后引入的 为了解决日益变多的数据量 默认是关闭了 可以在.conf里面修改 多线程负责的是处理网络I/O 具体来说

读取并解析指令以及回包。

单线程模式下是一个线程完成读取、解析、执行、将回包放入客户端缓冲区;
但在多线程模式下,会将不同的client放 入clients_ pending_ read任务队列中, 后续会通Round-Robin轮询负载均衡策略把这些client分给其他IO线程和主线程进行读取和解析;在回包的时候,也是利用Round-Robin轮询负 载均衡策略把等待回包队列中的任务连续均匀地分配给IO线程各自的
本地FIFO任务队列和主线程自己,主线程轮询等待所有IO线程完成回包任务

 

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

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

相关文章

罗勇军 →《算法竞赛·快冲300题》每日一题:“质因子数量” ← 快速幂、素数筛

【题目来源】http://oj.ecustacm.cn/problem.php?id1780http://oj.ecustacm.cn/viewnews.php?id1023【题目描述】 给出n个数字,你可以任意选择一些数字相乘,相乘之后得到新数字x。 其中,x的分数等于x不同质因子的数量。 请你计算所有选择数…

【Rust】Rust学习 第十四章进一步认识 Cargo 和 Crates.io

本章会讨论 Cargo 其他一些更为高级的功能,我们将展示如何: 使用发布配置来自定义构建将库发布到 crates.io使用工作空间来组织更大的项目从 crates.io 安装二进制文件使用自定义的命令来扩展 Cargo Cargo 的功能不止本章所介绍的,关于其全…

蓝蓝设计-ui设计公司-界面设计案例作品

泛亚高科-光伏电站控制系统界面设计 html前端 | 交互设计 | 视觉设计 | 图标设计 泛亚高科(北京)科技有限公司(以下简称“泛亚高科”),一个以实时监控、高精度数值计算为基础的科技公司, 自成立以来,组成了以博士、硕…

【Java 动态数据统计图】动态数据统计思路案例(动态,排序,containsKey)五(117)

需求:前端根据后端的返回数据:画统计图; 1.动态获取地域数据以及数据中的平均值,按照平均值降序排序; 说明: X轴是动态的,有对应区域数据则展示; X轴 区域数据降序排序;…

Android Studio实现解析HTML获取图片URL,将URL存到list,进行瀑布流展示

目录 效果展示build.gradle(app)添加的依赖(用不上的可以不加)AndroidManifest.xml错误代码activity_main.xmlitem_image.xmlMainActivityImage适配器ImageModel 接收图片URL效果展示 build.gradle(app)添加的依赖(用不上的可以不加) dependencies {implementation co…

Matlab 在一张图中画多个机械臂

在matlab中第一次画机械臂时,可能会出现的问题是Link函数不识别(如出现Link输入参数不对等) 这大概率是因为缺少matlab工具箱,如图 需要下载该软件包,然后用Matlab打开,就能自动安装到matlab中。下载地址在这个超链接…

最强自动化测试框架Playwright(34)CDPSession

在 Playwright 中,CDPSession 类是用于与浏览器的 Chrome DevTools Protocol (CDP) 会话进行交互的对象。CDP 是与Chromium浏览器通信的底层协议,它提供了许多与浏览器进行交互和控制的功能。 CDPSession 类提供了执行底层 CDP 命令的方法,并…

linux--epoll

epoll 参考文献 https://www.cnblogs.com/lojunren/p/3856290.html https://www.51cto.com/article/717096.html linux下的I/O复用epoll详解 要深刻理解epoll,首先得了解epoll的三大关键要素:mmap、红黑树、链表。 IO多路复用 首先需要了解什么是IO多…

探讨uniapp的网络通信问题

uni-app 中有很多原生的 API,其中我们经常会用到的肯定有:uni.request(OBJECT) method 有效值 注意:method有效值必须大写,每个平台支持的method有效值不同,详细见下表。 success 返回参数说明 data 数据说明 最终…

应急响应-Webshell

文章目录 一、Webshell概述什么是WebshellWebshell分类基于编程语言基于文件大小/提供的功能多少 Webshell 检测方法 二、常规处置方法三、技术指南1、初步预判2、 Webshell排查3、Web日志分析(查找攻击路径及失陷原因)4、系统排查4.1 Windows4.2 Linux …

Jmeter 二次开发 函数助手 AES加解密

Jmeter 二次开发 函数助手 AES加解密 1. 环境准备2. 关键技术说明2.1 离线导包2.2 示例代码 3. 代码包4. 结果演示 1. 环境准备 IDE :IntelliJ IDEA 2021.1.1 x64JAVA环境 :jdk1.8.0_251离线导包:导入Jmeter安装目录下lib/ext下的ApacheJmet…

【使用群晖远程链接drive挂载电脑硬盘】

文章目录 前言1.群晖Synology Drive套件的安装1.1 安装Synology Drive套件1.2 设置Synology Drive套件1.3 局域网内电脑测试和使用 2.使用cpolar远程访问内网Synology Drive2.1 Cpolar云端设置2.2 Cpolar本地设置2.3 测试和使用 3. 结语 前言 群晖作为专业的数据存储中心&…

ViewFs And Federation On HDFS

序言 ViewFs 是在Federation的基础上提出的,用于通过一个HDFS路径来访问多个NameSpace,同时与ViewFs搭配的技术是client-side mount table(这个就是具体的规则配置信息可以放置在core.xml中,也可以放置在mountTable.xml中). 总的来说ViewFs的其实就是一个中间层,用于去连接不…

药品最新研究信息查询系统

查找最新药物研究进展信息在患者治疗选择、医疗实践、科学研究、药物监管和政策制定、教育和学术研究等方面都具有重要的应用价值。它可以为各个领域的人员提供最新的科学依据和决策支持,促进医学领域的发展和提高医疗质量。 但在查找药物最新研究进展信息时通常需要…

08 - 追加commit和修改最新的commit message

查看所有文章链接:(更新中)GIT常用场景- 目录 文章目录 1. 追加提交2. 修改最新的commit message 1. 追加提交 将改动追加到上一次的commit 现在我已经修改了Readme文件并且已经add、commit操作,但是还没有push到远程仓库&#x…

Kafka 什么速度那么快

批量发送消息 Kafka 采用了批量发送消息的方式,通过将多条消息按照分区进行分组,然后每次发送一个消息集合,看似很平常的一个手段,其实它大大提升了 Kafka 的吞吐量。 消息压缩 消息压缩的目的是为了进一步减少网络传输带宽。而…

NLP文本匹配任务Text Matching [无监督训练]:SimCSE、ESimCSE、DiffCSE 项目实践

NLP文本匹配任务Text Matching [无监督训练]:SimCSE、ESimCSE、DiffCSE 项目实践 文本匹配多用于计算两个文本之间的相似度,该示例会基于 ESimCSE 实现一个无监督的文本匹配模型的训练流程。文本匹配多用于计算两段「自然文本」之间的「相似度」。 例如…

【数据结构】 链表简介与单链表的实现

文章目录 ArrayList的缺陷链表链表的概念及结构链表的分类单向或者双向带头或者不带头循环或者非循环 单链表的实现创建单链表遍历链表得到单链表的长度查找是否包含关键字头插法尾插法任意位置插入删除第一次出现关键字为key的节点删除所有值为key的节点回收链表 总结 ArrayLi…

p5.js 渐变填充的实现方式

theme: smartblue 本文简介 p5.js 作为一款艺术类的 canvas 库,对颜色方面的支持是挺下功夫的,比如本文要介绍的渐变方法。 lerpColor() 要实现渐变效果,可以使用 lerpColor() 方法。 lerpColor 的作用是混合两个颜色以找到一个介于它们之间的…

Llama 2免费托管及API提供

Llama 2 是 Meta 最新的文本生成模型,目前其性能优于所有开源替代方案。 推荐:用 NSDT编辑器 快速搭建可编程3D场景 1、强大的Llama 2 它击败了 Falcon-40B(之前最好的开源基础模型),与 GPT-3.5 相当,仅低…
最新文章