01_Redis单线程与多线程

01——Redis单线程与多线程

一、Redis是单线程还是多线程

在谈Redis的单线程或多线程时,需要根据版本来区分。

  1. 在redis 3.x之前,redis是单线程的
  2. 从redis 4.x开始,redis引入多线程。处理客户端请求时,使用单线程;在异步删除等操作时,使用多线程
  3. 在2020年发布的6.x以及2022年发布的7.x版本,使用全新的多线程来解决问题。

Redis重要里程碑:

  1. Redis 2.6 支持lua脚本
  2. Redis 3.0 支持集群
  3. Redis 4.0 混合持久化、多线程异步删除
  4. Redis 5.0 核心代码重构
  5. Redis 6.0 多线程IO

image-20230305184649796

二、Redis为什么选择单线程

Redis单线程

定义:主要是指Redis的网络IO和键值对读写是由一个线程来完成的,Redis在处理客户端的请求时(包括获取(Socket读)、解析、执行、内容返回(Socket写)),都是由一个顺序串的主线程处理,这就是所谓的“单线程”。这也是Redis对外提供键值存储服务的主要流程。

image-20230305185732100

但是Redis的其他功能,比如持久化RBD、AOF、异步删除、集群数据同步等,其实是由额外的线程执行的。

Redis命令工作线程是单线程的,但是,对整个Redis来说,是多线程的。

Redis在3.x版本时,性能依旧很快的主要原因:

  1. 基于内存操作: Redis的所有数据都存在内存中,因此所有的运算都是内存级别的
  2. 数据结构简单: Redis的数据结构是专门设计的,而这些简单的数据结构的查找和操作时间复杂度都是O(1)
  3. 多路复用和非阻塞IO: Redis使用IO多路复用功能来监听多个socket连接客户端,这样就可以使用一个线程连接来处理多个请求,减少线程切换带来的开销,同时也避免了IO阻塞操作
  4. 避免上下文切换: 因为是单线程模型,因此就避免了不必要的线程上下文切换和多线程竞争,省去了多线程切换带来的时间和性能上的消耗

在多CPU时代,Redis如何使用多个CPU?

官网:Redis是基于内存操作的,因此Redis的瓶颈可能是机器的内存或网络带宽而非CPU。既然CPU不是瓶颈,那么自然采用单线程。但是在Redis4.0中开始支持多线程了,例如:后台删除、备份等功能。

三、为什么Redis加入了多线程特性

单线程的痛点: 正常情况下,使用del删除数据很快,但是删除一个非常大的key,则会导致Redis主线程卡顿。

解决方案:使用惰性删除,把删除数据的工作交给后台的其他线程来完成。

  1. unlink key
  2. flushdb async
  3. flushall async

本质上来说,就是将耗时的操作从主线程剥离,交给BIO子线程来处理,减少主线程阻塞时间,从而减少因为耗时操作导致的性能和稳定性问题。

四、Redis多线程特性和IO多路复用

Redis性能影响因素:

  1. CPU,官网文档说明,CPU不大可能是Redis的性能瓶颈
  2. 内存,在当下的开发环境中,内存越来越便宜,因此内存也不性能瓶颈
  3. 网络IO:因为Redis从网络IO处理到实际的读写命令处理,都是由单个线程完成的,所以网络IO可能会成为Redis的性能瓶颈。

单个线程处理网络请求的速度,有可能跟不上底层网络硬件的速度。为了应对这个问题,Redis6、7采用多个IO线程来处理网络请求,提高网络请求处理的并行度。

Redis只是使用多线程来处理网络IO操作,此操作可以提升实例的整体处理性能。执行命令操作还是单线程,这就不用开发多线程的互斥枷锁机制。因此,Redis线程模型的实现就很简单。

主线程和IO线程是怎么协作完成请求处理的:

  1. 阶段一:服务端和客户端建立Socket连接,并分配处理线程

    首先,主线程负责接收建立连接的请求。当有客户端请求和实例建立Socket连接时,主线程会创建和客户端的连接,并把Socket放入全局等待队列中。紧接着,主线程通过轮训方法把Socket连接分配给IO线程。

  2. 阶段二:IO线程读取并解析请求

    主线程一旦把Socket分配给IO线程,就会进入阻塞状态,等待IO线程完成客户端请求(读取和解析)。因为有多个IO线程在并行处理,所以,这个过程很快就可以完成。

  3. 阶段三:主线程执行请求操作

    等到IO线程解析完请求,主线程还是会以单线程的方式执行这些命令操作。

  4. IO线程回写Socket和主线程清空全局队列

    当主线程执行完请求操作后,会把需要返回的结果写入缓冲区。然后,主线程阻塞等待,IO线程把结果写回到Socket中,并返回给客户端。和IO线程读取解析一样,IO线程回写Socket时,也是多个线程并发执行,所以速度很快。等到IO线程回写Socket完毕,主线程会清空全局队列,等待客户端的后续请求。

image-20230305200247468

image-20230305200405160

Unix网络编程中的五种IO模型:

  1. Blocking IO:阻塞IO

  2. NoneBlocking IO:非阻塞IO

  3. IO multiplexing:IO多路复用

    1. Linux世界:一切皆文件

      文件描述符,简称FD、句柄

      image-20230305201118910

    2. IO多路复用是什么

      一种同步的IO模型,实现一个线程监视多个文件句柄,一旦某个文件句柄就绪,就能通知到对应的应用程序进行相应的读写操作,没有文件句柄就绪时,就会阻塞应用程序,从而释放CPU资源。

      1. IO:网络IO,在操作系统层面,指数据在内核态和用户态之间的读写操作
      2. 多路:多个客户端连接(连接就是套接字描述符,即socket或者channel)
      3. 复用:复用一个或几个线程
      4. IO多路复用:也就是说一个或一组线程处理多个TCP连接,使用单进程就能够实现同时处理多个客户端的连接,无需创建或者维护过多的进程、线程
      5. 实现IO多路复用的模型有三种:select、poll、epoll
    3. epoll

      image-20230305202006354

      image-20230305202219213

    4. 总结

      image-20230305202318018

    5. Redis问什么这么快

      IO多路复用+epoll函数,才是redis为什么这么快的直接原因,而不是单线程命令+redis安装在内存中。

      image-20230305202714218

      image-20230305202849547

      image-20230305202930956

  4. signal driven IO:信号驱动IO

  5. asynchronous IO:异步IO

五、Redis7是否默认开启多线程

如果在实际应用中,发现redis CPU开销不大但吞吐量却没有提升,可以考虑使用redis7的多线程机制,加速网络处理,进而提升实例的吞吐量。

Redis7讲所有的数据放在内存中,内存的响应时长大约是100纳秒,对于小的数据包,Redis服务器可以处理8w到10w的QPS,这也是Redis处理的极限,对于大多数业务来说,单线程Redis已经足够使用了。

在redis6、7中,多线程机制默认是关闭的,如果需要使用redis多线程功能,需要修改redis.conf配置文件:

# 启用多线程
io-thread-do-reads yes
# 设置线程个数。官方建议:4核cpu,线程数设置为2或3;8核cpu,设置为6。线程数一定要小于机器核数,线程数并不是越大越好
io-threads 6

六、总结

image-20230305221648688

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

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

相关文章

B-树和B+树的区别

B-树和B树的区别 一、B-tree数据存储 在下图中 P 代表的是指针,指向的是下一个磁盘块。在第一个节点中的 16、24 就是代表我们的 key 值是什么。date 就是这个 key 值对应的这一行记录是什么。 假设寻找 key 为 33 的这条记录,33 在 16 和 34 中间&am…

QT TLS initialization failed问题(已解决) QT基础入门【网络编程】openssl

问题: qt.network.ssl: QSslSocket::connectToHostEncrypted: TLS initialization failed 这个问题的出现主要是使用了https请求:HTTPS ≈ HTTP + SSL,即有了加密层的HTTP 所以Qt 组件库需要OpenSSL dll 文件支持HTTPS 解决: 1.加入以下两行代码获取QT是否支持opensll以…

如何在出差期间远程访问企业ERP系统?内网穿透解决您的难题!

文章目录 概述1.查看象过河服务端端口2.内网穿透3. 异地公网连接4. 固定公网地址4.1 保留一个固定TCP地址4.2 配置固定TCP地址 5. 使用固定地址连接 概述 ERP系统对于企业来说重要性不言而喻,不管是财务、生产、销售还是采购,都需要用到ERP系统来协助。…

SharkTeam:Worldcoin运营数据及业务安全分析

Worldcoin的白皮书中声明,Worldcoin旨在构建一个连接全球人类的新型数字经济系统,由OpenAI创始人Sam Altman于2020年发起。通过区块链技术在Web3世界中实现更加公平、开放和包容的经济体系,并将所有权赋予每个人。并且希望让全世界每一个人都…

Web3和去中心化:互联网的下一个演化阶段

文章目录 Web3和去中心化的定义Web3:去中心化: 为什么Web3和去中心化如此重要?数据隐私和安全:去中心化的创新:去除中间商: Web3和去中心化的应用领域去中心化金融(DeFi)&#xff1a…

Linux驱动开发之点亮三盏小灯

头文件 #ifndef __HEAD_H__ #define __HEAD_H__//LED1和LED3的硬件地址 #define PHY_LED1_MODER 0x50006000 #define PHY_LED1_ODR 0x50006014 #define PHY_LED1_RCC 0x50000A28 //LED2的硬件地址 #define PHY_LED2_MODER 0x50007000 #define PHY_LED2_ODR 0x50007014 #define…

机器学习深度学习——NLP实战(情感分析模型——数据集)

👨‍🎓作者简介:一位即将上大四,正专攻机器学习的保研er 🌌上期文章:机器学习&&深度学习——BERT(来自transformer的双向编码器表示) 📚订阅专栏:机器…

Unity如何控制声音大小(包括静音功能)

一:UGUI制作 1. 首先在【层级】下面创建UI里面的Slider组件。设置好它对应的宽度和高度。 2.调整Slider滑动条的填充颜色。一般声音颜色我黄色,所以我们也调成黄色。 我们尝试滑动Slider里面的value。 a.滑动前。 b.滑动一半。 c.滑动完。 从以上滑动va…

DeFINE:用于神经序列建模的深度分解输入令牌嵌入

一、说明 DeFINE,是华盛顿大学和艾伦人工智能开发的自然语言处理工具,可以处理的范围是:NLP、语言模型、LM、神经机器翻译、NMT、变压器、变压器-XL等;本文对token-bedding进行生成。 借助DeFINE,Transformer-XL可以在…

汽车级36V、4A同步降压转换器MAX20404AFOD/VY、MAX20404AFOC/VY、MAX20404AFOA/VY开关稳压器

MAX20404是小型同步降压转换器,集成了高端和低端开关。这些IC均设计为可在3V到36V的宽输入电压范围内提供高达4A的电流。电压质量可以通过观察PGOOD信号来监测。该器件可以在99%的占空比下运行,非常适合汽车和工业应用。 MAX20404提供可编程输出电压或5…

Debian查询硬件状态

很早以前写过一个查询树霉派硬件状态的文章,用是Python写的一个小程序。里面用到了vcgencmd这个测温度的内部命令,但这个命令在debian里面没有,debian里只有lm_sensors的外部命令,需要安装:apt-get install lm_sensors…

python:tkinter + cef 模仿 mdict 界面

cefpython3 其上游是C开发的CEF(基于webkit、V8), CEF 即 (Chromium Embedder Framework), 是基于Google Chromium项目的开源 Web browser控件(WebView)。 可查看github文档:cefpython api pip install cefpython3 c…

TCP编程流程(补充)

目录 1、listen: 2、listen、tcp三次握手 3、 发送缓冲区和接收缓冲区: 4、tcp编程启用多线程 1、listen: 执行listen会创建一个监听队列 listen(sockfd,5) 2、listen、tcp三次握手 三次握手 3、 发送缓冲区和接收缓冲区:…

SpringBoot复习:(52)不再需要使用@EnableTransactionManagement的原因

在Spring项目中,要用事务,需要EnableTransactionManagement注解加Transactional注解。而在SpringBoot项目,有事务的自动配置类TransactionAutoConfiguration,代码如下: 可以在其内部类EnableTransactionManagementConfiguratio…

2017年3月全国计算机等级考试真题(C语言二级)

2017年3月全国计算机等级考试真题(C语言二级) 第1题 每个学校有一名校长,且不同学校的校长可以是同一人,则实体学校和实体校长间的联系是 A. 多对一 B. 多对多 C. 一对一 D. 一对多 正确答案:A 第2题 若有以下定义…

[JavaWeb]【一】入门JavaWeb开发总概及HTML、CSS、JavaScript

目录 一 特色 二 收获​编辑 三 什么是web? 四 网站的工作流程 五 web网站的开发模式​编辑 六 web开发课程学习安排 七、初始web前端 八 HTML、CSS 8.1 什么是HTNL\CSS(w3cschool) 8.2 HTML快速入门 8.3 VS Code开发工具 8.3.1 插件 8.3.2 主题(改变颜色&…

Python写一个创意五子棋游戏

前言 在本教程中,我们将使用Python写一个创意五子棋游戏 📝个人主页→数据挖掘博主ZTLJQ的主页 个人推荐python学习系列: ☄️爬虫JS逆向系列专栏 - 爬虫逆向教学 ☄️python系列专栏 - 从零开始学python 首先 GomokuGame 类的构造函数 __ini…

Redis、Memcache和MongoDB的区别

>>Memcached Memcached的优点: Memcached可以利用多核优势,单实例吞吐量极高,可以达到几十万QPS(取决于key、value的字节大小以及服务器硬件性能,日常环境中QPS高峰大约在4-6w左右)。适用于最大程度…

图数据库_Neo4j_Centos7.9安装Neo4j社区版3.5.4_基于jdk1.8---Neo4j图数据库工作笔记0011

首先上传安装包,到opt/soft目录 然后看一下jdk安装的是什么版本的,因为在neo4j 4以后就必须要用jdk11 以上的版本,我这里还用着jdk1.8 所以 我这里用3.5.4的版本 关于下载地址: https://dist.neo4j.org/neo4j-community-3.5.4-unix.tar.gz 然后再去解压到/opt/module目录下 …

【目标检测】目标检测 相关学习笔记

目标检测算法 PASCALVOC2012数据集 挑战赛主要分为 图像分类 目标检测 目标分割 动作识别 数据集分为四个大类 交通(飞机 船 公交车 摩托车) 住房(杯子 椅子 餐桌 沙发) 动物(鸟 猫 奶牛 狗 马 羊) 其他&a…