01_Redis单线程与多线程

news2024/9/22 1:02:42

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.coloradmin.cn/o/902113.html

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

相关文章

二维码智慧门牌管理系统:推动企业办公信息化发展的利器

文章目录 前言一、利用二维码智慧门牌管理系统提升企业管理效率二、实现企业信息互通与协作的新模式三、数据安全性与隐私保障 前言 随着科技的不断发展,中国的行政机构改革不断深化,社会也在快速智能化的进程中不断前进。这背景下,传统的纸…

小程序定位到 胶囊的三个点大概中间

话不多说,先上效果图 这个功能实现思路: 首先先拿到这一张整图(快捷,精确)然后获取整个导航栏高度(自定义导航栏,非自定义导航栏忽略这一步)获取三个点的做偏移量,把高度和偏移量给到一个定位到盒子,这个盒子里就放这个图片&…

终极Shell:Zsh(CentOS7 安装 zsh 及 配置 Oh my zsh)

CentOS7 安装 zsh 及 配置 Oh my zsh 我们在通过Shell操作linux终端时,配置、颜色区分、命令提示大都达不到我们预期的效果或者操作较为繁琐。 今天就来介绍一款终极一个及其好用的类Linux系统中的终端软件,江湖称之为马车中的跑车,跑车中的飞行车,史称『终极 Shell…

Linux设置临时目录路径的解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

详解junit

目录 1.概述 2.断言 3.常用注解 3.1.Test 3.2.Before 3.3.After 3.4.BeforeClass 3.5.AfterClass 4.异常测试 5.超时测试 6.参数化测试 1.概述 什么是单元测试: 单元测试,是针对最小的功能单元编写测试代码,在JAVA中最小的功能单…

SAP BTEs 业务交易事件/增强(Business Transaction Event)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 目录 前言 一、BTEs是什么? 二、使用步骤 1.查找BTE event 2.处理FM 总结 前言 SAP BTEs是一种新型的增强方式,可以通过事务代码FIFB打开&#…

Windows系统搭建Gitblit服务器

目录 介绍安装Java环境配置环境变量 下载Gitbilt配置Gitbilt 介绍 GitBlit是一个用于搭建和管理Git服务器的开源工具。它是使用Java语言编写的,并且需要Java环境来运行。 1、跨平台性:Java是一种具有跨平台性的编程语言,可以在多个操作系统…

知识图谱入门:使用Python创建知识图,分析并训练嵌入模型

本文中我们将解释如何构建KG、分析它以及创建嵌入模型。 构建知识图谱 加载我们的数据。在本文中我们将从头创建一个简单的KG。 import pandas as pd# Define the heads, relations, and tailshead [drugA, drugB, drugC, drugD, drugA, drugC, drugD, drugE, gene1, gene2,g…

08-MySQL-基础篇-约束

约束 前言约束示例 外键约束示例外键删除/更新行为语法CASCADESET NULL 前言 本篇来学习下MySQL表中字段的约束 约束 概念:约束是作用于表中字段上的规则,用于限制存储在表中的数据。目的:保证数据库中数据的正确、有效性和完整性。分类 …

Oracle故障案例之-19C时区补丁DSTV38更新

📢📢📢📣📣📣 哈喽!大家好,我是【IT邦德】,江湖人称jeames007,10余年DBA工作经验 一位上进心十足的【大数据领域博主】!😜&#x1f61…

基于jeecg-boot的flowable流程收回功能实现(全网首创功能)

更多nbcio-boot功能请看演示系统 gitee源代码地址 后端代码: https://gitee.com/nbacheng/nbcio-boot 前端代码:https://gitee.com/nbacheng/nbcio-vue.git 在线演示(包括H5) : http://122.227.135.243:9888 对于之前的flowable流程,之前有撤回,拒绝,退回等…

如何做好服务性能测试

一、什么是性能测试 新功能上线或切换底层数据库或扩容调优,根据实际业务场景的需要,做必要的性能压测,收集性能数据,作为上线的基准报告。 性能测试一般分一下几个阶段: 1. 性能测试 并发量小(jmeter 并…

【C++】详解内存中的堆和栈

2023年8月20日,周日早上 感觉很多东西还没吃透,很多疑问还没解决。 这篇文章可能会不定期更新。 还没解释为什么栈的空间有限,而堆的空间很大 还没解释栈和堆在内存中的位置 ...... 目录 怎么申请栈空间语法举例说明 怎么申请堆空间语法…

无涯教程-PHP - 常量声明

常量值不能更改。默认情况下,常量区分大小写。按照约定,常量标识符始终为大写。与变量不同,您不需要具有"$"的常量。 constant 函数 如名称所示,此函数将返回常量的值。 当您要检索常量的值但不知道其名称时&#xf…

6种方法Word中的页眉横线如何删除

01 如何给Word添加页眉? 方法1: 打开Word文档,将鼠标放在Word顶部,双击鼠标,就可以进入页眉编辑状态,这时候,直接添加页眉内容就好了。 方法2: 在Word文档顶部菜单栏点击【插入】…

拒绝摆烂!C语言练习打卡第四天

🔥博客主页:小王又困了 📚系列专栏:每日一练 🌟人之为学,不日近则日退 ❤️感谢大家点赞👍收藏⭐评论✍️ 目录 一、选择题 📝1.第一题 📝2.第二题 &#x1f4d…

【Python机器学习】实验14 手写体卷积神经网络(PyTorch实现)

文章目录 LeNet-5网络结构(1)卷积层C1(2)池化层S1(3)卷积层C2(4)池化层S2(5)卷积层C3(6)线性层F1(7)线性层F2 …

开启AI创新之旅!“华为云杯”2023人工智能应用创新大赛等你来挑战

简介 近年来,人工智能技术的发展如日中天,深刻地改变着我们的生活方式和产业格局。 为了培养AI人才,持续赋能AI企业,推进国家新一代人工智能开放创新平台建设,打造更加完善的AI技术创新生态,华为&#xf…

从NLP到聊天机器人

一、说明 今天,当打电话给银行或其他公司时,听到电话另一端的机器人向你打招呼是很常见的:“你好,我是你的数字助理。请问你的问题。是的,机器人现在不仅可以说人类语言,还可以用人类语言与用户互动。这是由…

中大型企业选择CRM系统必备五大功能是什么?

中大型企业的特点是客户数量多,业务复杂,需求多样,对CRM系统的功能和作用有着更高的要求。下面我们从五个方面来为您介绍一下,中大型企业CRM系统的功能及作用。 客户信息管理: CRM系统可以帮助企业收集、存储、分析客…