Redis什么这么快和Redis单线程模型和多线程

概述

1、完全基于内存,绝大部分请求是纯粹的内存操作,非常快速。数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1);
2、数据结构简单,对数据操作也简单,Redis中的数据结构是专门进行设计的;
3、采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 CPU,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗;
4、非阻塞IO多路复用机制
5、使用底层模型不同,它们之间底层实现方式以及与客户端之间通信的应用协议不一样,Redis直接自己构建了VM 机制 ,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求;

基于内存存储

Redis 是在内存中进行键值存储。
Redis 中的每次读写操作都相当于从内存的变量中进行读写。
访问内存比直接访问磁盘快几个数量级,因此Redis 比其他数据存储快得多。

优化的数据结构
作为内存数据存储,Redis 利用各种底层数据结构来高效存储数据,无需担心如何将它们持久化到持久存储中。
例如,Redis list 是使用链表实现的,它允许在列表的头部和尾部附近进行恒定时间 O(1) 插入和删除。
另一方面,Redis sorted set 是通过跳跃列表实现的,可以实现更快的查询和插入。
简而言之,无需担心数据持久化,Redis 中的数据可以更高效地存储,以便通过不同的数据结构进行快速检索。

在这里插入图片描述

单线程

Redis 中的写入和读取速度非常快,并且 CPU 使用率从来不是 Redis 关心的问题。
根据 Redis 官方文档,在普通 Linux 系统上运行时,Redis 每秒最多可以处理 100 万个请求。
通常瓶颈来自于网络 I/O, Redis 中的处理时间大部分浪费在等待网络 I/O 上。
虽然多线程架构允许应用程序通过上下文切换并发处理任务,但这对 Redis 的性能增益很小,因为大多数线程最终会在 I/O 中被阻塞。
所以 Redis 采用单线程架构,有如下好处
● 最大限度地减少由于线程创建或销毁而产生的 CPU 消耗
● 最大限度地减少上下文切换造成的 CPU 消耗
● 减少锁开销,因为多线程应用程序需要锁来进行线程同步,而这容易出现错误
● 能够使用各种“线程不安全”命令,例如 Lpush

非阻塞IO多路复用机制

Redis采用epoll做为I/O多路复用技术的实现,再加上Redis自身的事件处理模型将epoll中的连接,读写,关闭
都转换为了事件,不在I/O上浪费过多的时间,使得Redis在网络 IO 操作中能并发处理大量的客户端请求,实现了高吞吐率。

为了处理传入的请求,服务器需要在套接字上执行系统调用,以将数据从网络缓冲区读取到用户空间。
这通常是阻塞操作,线程被阻塞并且在完全接收到来自客户端的数据之前不能执行任何操作。
为什么我们不能在只有确定套接字中的数据已准备好读取时,才执行系统调用嘞?
这就是 I/O 多路复用发挥作用的地方。
I/O 多路复用模块同时监视多个套接字,并且仅返回可读的套接字。
准备读取的套接字被推送到单线程事件循环,并由相应的处理程序使用响应式模型进行处理。
总之,
● 网络 I/O 速度很慢,因为其阻塞特性,
● Redis 收到命令后可以快速执行,因为这在内存中执行,操作速度很快,
所以 Redis 做出了以下决定,
● 使用 I/O 多路复用来缓解网络 I/O 缓慢问题
(1)多路 I/O 复用模型
多路I/O复用模型是利用 select、poll、epoll 可以同时监察多个流的 I/O 事件的能力,在空闲的时候,会把当前线程阻塞掉,当有一个或多个流有 I/O 事件时,就从阻塞态中唤醒,于是程序就会轮询一遍所有的流(epoll 是只轮询那些真正发出了事件的流),并且只依次顺序的处理就绪的流,这种做法就避免了大量的无用操作。
这里“多路”指的是多个网络连接,“复用”指的是复用同一个线程。采用多路 I/O 复用技术可以让单个线程高效的处理多个连接请求(尽量减少网络 IO 的时间消耗),且 Redis 在内存中操作数据的速度非常快,也就是说内存内的操作不会成为影响Redis性能的瓶颈,主要由以上几点造就了 Redis 具有很高的吞吐量
多路I/O复用技术可以让单个线程高效的处理多个连接请求,而Redis使用用epoll作为I/O多路复用技术的实现。并且,Redis自身的事件处理模型将epoll中的连接、读写、关闭都转换为事件,不在网络I/O上浪费过多的时间。
● I/O :网络 I/O
● 多路 :多个网络连接
● 复用:复用同一个线程。
● IO多路复用其实就是一种同步IO模型,它实现了一个线程可以监视多个文件句柄;一旦某个文件句柄就绪,就能够通知应用程序进行相应的读写操作;而没有文件句柄就绪时,就会阻塞应用程序,交出cpu。
在这里插入图片描述

Redis基于Reactor模式开发了网络事件处理器,这个处理器被称为文件事件处理器(file event handler)。它的组成结构为4部分:多个套接字、IO多路复用程序、文件事件分派器、事件处理器。因为文件事件分派器队列的消费是单线程的,所以Redis才叫单线程模型
文件事件处理器使用 I/O 多路复用(multiplexing)程序来同时监听多个套接字, 并根据套接字目前执行的任务来为套接字关联不同的事件处理器 当被监听的套接字准备好执行连接应答(accept)、读取(read)、写入(write)、关闭(close)等操作时, 与操作相对应的文件事件就会产生, 这时文件事件处理器就会调用套接字之前关联好的事件处理器来处理这些事件,虽然文件事件处理器以单线程方式运行, 但通过使用 I/O 多路复用程序来监听多个套接字, 文件事件处理器既实现了高性能的网络通信模型, 又可以很好地与 redis 服务器中其他同样以单线程方式运行的模块进行对接, 这保持了 Redis 内部单线程设计的简单性

IO 多路复用机制
IO多路复用是一种同步的IO模型。利用IO多路复用模型,可以实现一个线程监视多个文件句柄;一旦某个文件
句柄就绪,就能够通知到对应应用程序进行相应的读写操作;没有文件句柄就绪时就会阻塞应用程序,从而释放出CPU资源。
IO可以理解为,在操作系统中,数据在内核态和用户态之间的读、写操作,大部分情况下是指网络IO多路大部分情况下是指多个TCP连接,也就是多个Socket 或者多个Channel;

2 select模型

select模型,它的基本原理是,采用轮询和遍历的方式。也就是说,在客户端操作服务器时,会创建三种文件描
述符,简称FD。分别是writefds(写描述符)、readfds(读描述符)和 exceptfds(异常描述符)。
而select会阻塞监视这三种文件描述符,等有数据、可读、可写、出异常或超时都会返回;
返回后通过遍历fdset,也就是文件描述符的集合,来找到就绪的FD,然后,触发相应的IO操作。
它的优点是跨平台支持性好,几乎在所有的平台上支持。
它的缺点也很明显,由于select是采用轮询的方式进行全盘扫描,因此,随着FD数量增多而导致性能下降。
因此,每次调用select()方法,都需要把FD集合从用户态拷贝到内核态,并进行遍历。而操作系统对单个进程打
开的FD数量是有限制的,一般默认是1024个。虽然,可以通过操作系统的宏定义FD_SETSIZE修改最大FD数量限制,但是,在IO吞吐量巨大的情况下,效率提升仍然有限。

3 poll模型

poll 模型的原理与select模型基本一致,也是采用轮询加遍历,唯一的区别就是 poll 采用链表的方式来存储FD。
所以,它的优点点是没有最大FD的数量限制。
它的缺点和select一样,也是采用轮询方式全盘扫描,同样也会随着FD数量增多而导致性能下降。

4 epoll模型

由于select和poll都会因为吞吐量增加而导致性能下降,因此,才出现了epoll模型。
epoll模型是采用时间通知机制来触发相关的IO操作。它没有FD个数限制,而且从用户态拷贝到内核态只需要一
次。它主要通过系统底层的函数来注册、激活FD,从而触发相关的 IO 操作,这样大大提高了性能。主要是通过调用以下三个系统函数:
1、epoll_create()函数,在系统启动时,会在Linux内核里面申请一个B+树结构的文件系统,然后,返回epoll
对象,也是一个FD。
2、epoll_ctl()函数,每新建一个连接的时候,会同步更新epoll对象中的FD,并且绑定一个 callback回调函数。
3、epoll_wait()函数,轮询所有的callback集合,并触发对应的 IO 操作
所以,epoll模型最大的优点是将轮询改成了回调,大大提高了CPU执行效率,也不会随FD数量的增加而导致效
率下降。当然,它也没有FD数量限制,也就是说,它能支持的FD上限是操作系统的最大文件句柄数。一般而言,1G内存大概支持 10 万个句柄。分布式系统中常用的组件如Redis、Nginx都是优先采用epoll模型。
它的缺点是只能在Linux下工作。

Redis是单线程模型和多线程

Redis6.0,它的执行命令操作内存的仍然是个单线程
单线程模型
Redis是单线程模型的,而单线程避免了CPU不必要的上下文切换和竞争锁的消耗。也正因为是单线程,如果某个命令执行过长(如hgetall命令),会造成阻塞。Redis是面向快速执行场景的数据库。,所以要慎用smembers和lrange、hgetall等命令。
Redis 6.0 引入了多线程提速,它的执行命令操作内存的仍然是个单线程。
Redis6.0之前是单线程的,Redis6.0之后开始支持多线程;
redis内部使用了基于epoll的多路服用,也可以多部署几个redis服务器解决单线程的问题;
redis主要的性能瓶颈是内存和网络;
内存好说,加内存条就行了,而网络才是大麻烦,所以redis6内存好说,加内存条就行了;
而网络才是大麻烦,所以redis6.0引入了多线程的概念,
redis6.0在网络IO处理方面引入了多线程,如网络数据的读写和协议解析等,需要注意的是,执行命令的核心模块还是单线程的
Redis6.0之前,Redis在处理客户端的请求时,包括读socket、解析、执行、写socket等都由一个顺序串行的主线程处理,这就是所谓的“单线程”。
Redis6.0之前为什么一直不使用多线程?使用Redis时,几乎不存在CPU成为瓶颈的情况, Redis主要受限于内存和网络。例如在一个普通的Linux系统上,Redis通过使用pipelining每秒可以处理100万个请求,所以如果应用程序主要使用O(N)或O(log(N))的命令,它几乎不会占用太多CPU。
redis使用多线程并非是完全摒弃单线程,redis还是使用单线程模型来处理客户端的请求,只是使用多线程来处理数据的读写和协议解析,执行命令还是使用单线程。
这样做的目的是因为redis的性能瓶颈在于网络IO而非CPU,使用多线程能提升IO读写的效率,从而整体提高redis的性能。

为什么Redis 6.0+ 引入多线程

● Redis 3.x 版本是单线程的,存在 大key 删除问题;
● Redis 4.x 版本支持了部分多线程操作,主要是为了解决 3.x 的大key操作导致的超时性能问题;
● Redis 6.x 版本是多线程的。目的是降低网络IO的时间消耗
Redis 6.0 引入了一些新特性,其中非常受关注的一个特性就是多线程。在 4.0 之前 Redis 是单线程的,因为单线程的优点很明显,不但降低了 Redis 内部实现的复杂性,也让所有操作都可以在无锁的情况下进行,并且不存在死锁和线程切换带来的性能以及时间上的消耗。但是其缺点也很明显,单线程机制导致 Redis 的 QPS(Query Per Second,每秒查询数)很难得到有效的提高(虽然已经够快了,但人毕竟还是要有更高的追求的)。
而 Redis 从 4.0 版本开始引入了多线程,但是此版本的多线程主要用于大数据量的异步删除,对于非删除操作的意义并不是很大。
但 Redis 6.0 中的多线程则是真正为了提高 I/O 的读写性能而引入的,它的主要实现思路是将主线程的 I/O 读写任务拆分给一组独立的子线程去执行,也就是说从 socket 中读数据和写数据不再由主线程负责,而是交给了多个子线程,这样就可以使多个 socket 的读写并行化了。这么做的原因就在于,虽然在 Redis 中使用了 I/O 多路复用和非阻塞 I/O,但我们知道数据在内核态空间和用户态空间之间的拷贝是无法避免的,而数据的拷贝这一步是阻塞的,并且当数据量越大时拷贝所需要的时间就越多。所以 Redis 在 6.0 引入了多线程,用于分摊同步读写 I/O 压力,从而提升 Redis 的 QPS。但是注意:Redis 的命令本身依旧是由 Redis 主线程串行执行的,只不过具体的读写操作交给独立的子线程去执行了(后面会详细说明 Redis 的主线程和子线程之间是如何协同的),而这么做的好处就是不需要为 Lua 脚本、事务的原子性而额外开发多线程互斥机制,这样一来 Redis 的线程模型实现起来就简单多了。因为和之前一样,所有的命令依旧是由主线程串行执行的,只不过具体的读写任务交给了子线程。

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

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

相关文章

二叉树入门

这篇博客通过手动创建的一个简单二叉树,实现二叉树遍历,返回节点,叶子个数,查找结点等相关操作。 1. 二叉树的概念 二叉树不为空时,由根节点,左/右子树组成,逻辑结构如下,当二叉树…

Postman(注册,使用,作用)【详解】

目录 一、Postman 1. Postman介绍 2. 安装Postman 3. 注册帐号再使用(可保存测试记录) 4. 创建workspace 5. 测试并保存测试记录 一、Postman postman工具可以发送不同方式的请求,浏览器只能发送get请求(所有用这个工具) 在前后端分离开发模式下,前端技术人员…

Spring Boot中SQL语句报错

报错原因: You have an error in your SQL syntax 你的SQL语句出现错误 报错位置: check the manual that corresponds to your MySQL server version for the right syntax to use near :/sql/schema.sql.t_film at line 1 在:/sql/schema.sql附近使用…

主网NFT的发布合约

1.什么是nft? NFT:Non-fungible-token 非同质化货币 2.新建suimove项目 使用sui move new 项目名命令新建sui move项目 sui move new nft_qyx项目结构如下: 3.写nft合约 module qyx123::nft{use sui::object::{Self, UID};use sui::transfer;use sui::tx_context::{Sel…

【工具】Raycast – Mac提效工具

引入 以前看到同事们锁屏的时候,不知按了什么键,直接调出这个框,然后输入lock屏幕就锁了。 跟我习惯的按Mac开机键不大一样。个人觉得还是蛮炫酷的~ 调研 但是由于之前比较繁忙,这件事其实都忘的差不多了&#xff0…

JVM-垃圾收集底层算法实现

三色标记 背景描述 在并发标记的过程中,因为标记期间应用线程还在继续跑,对象间的引用可能发生变化,多标和漏标的情况就有可能发生。 如何解决上面的问题? 引入“三色标记” 意思就是,把Gcroots可达性分析遍历对象过程…

BUUCTF---[MRCTF2020]你传你呢1

1.题目描述 2.打开题目链接 3.上传shell.jpg文件&#xff0c;显示连接成功&#xff0c;但是用蚁剑连接却连接不上。shell文件内容为 <script languagephp>eval($_REQUEST[cmd]);</script>4.用bp抓包&#xff0c;修改属性 5.需要上传一个.htaccess的文件来把jpg后缀…

[递归、搜索、回溯]----递归

前言 作者&#xff1a;小蜗牛向前冲 专栏&#xff1a;小蜗牛算法之路 专栏介绍&#xff1a;"蜗牛之道&#xff0c;攀登大厂高峰&#xff0c;让我们携手学习算法。在这个专栏中&#xff0c;将涵盖动态规划、贪心算法、回溯等高阶技巧&#xff0c;不定期为你奉上基础数据结构…

【操作系统概念】 第9章:虚拟内存管理

文章目录 0.前言9.1 背景9.2 按需调页9.2.1 基本概念9.2.2 按需调页的性能 9.3 写时复制9.4 页面置换9.4.1 基本页置换9.4.2 FIFO页置换9.4.3 最优(Optimal)置换9.4.4 LRU&#xff08;Least Recently Used&#xff09;页置换9.4.5 近似LRU页置换9.4.6 页缓冲算法 9.5 帧分配9.5…

探索数据结构:单链表的实战指南

✨✨ 欢迎大家来到贝蒂大讲堂✨✨ &#x1f388;&#x1f388;养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 所属专栏&#xff1a;数据结构与算法 贝蒂的主页&#xff1a;Betty‘s blog 前言 在上一章节中我们讲解了数据结构中的顺序表&#xff0c;知道了顺序…

3.8 动态规划 背包问题

一.01背包 46. 携带研究材料&#xff08;第六期模拟笔试&#xff09; (kamacoder.com) 代码随想录 (programmercarl.com) 携带研究材料: 时间限制&#xff1a;5.000S 空间限制&#xff1a;128MB 题目描述: 小明是一位科学家&#xff0c;他需要参加一场重要的国际科学大会…

2001-2022年上市公司利润表数据

2001-2022年上市公司利润表数据 1、时间&#xff1a;2001.12.31-2022.12.31 2、范围&#xff1a;上市公司 3、指标&#xff1a;证券代码、证券简称、统计截止日期、报表类型、投资收益、其中&#xff1a;对联营企业和合营企业的投资收益、公允价值变动收益、营业利润、其他综…

探讨2024年AI辅助研发的趋势

一、引言 随着科技的飞速发展&#xff0c;人工智能&#xff08;AI&#xff09;已经成为当今时代最具变革性的技术之一。AI的广泛应用正在重塑各行各业&#xff0c;其中&#xff0c;AI辅助研发作为科技和工业领域的一大创新热点&#xff0c;正引领着研发模式的深刻变革。从医药…

电脑小问题:Windows更新后黑屏

Windows 更新后黑屏解决方法 在 Windows 更新后&#xff0c;伴随了一个小问题&#xff0c;电脑启动后出现了桌面黑屏。原因可能是火绒把 explorer.exe 当病毒处理了。 下面讲解 Windows 更新后黑屏的解决方法&#xff0c;步骤如下&#xff1a; 1. 按 ctrl alt delete 组合键…

C语言从入门到精通 第十一章(文件操作)

写在前面&#xff1a; 本系列专栏主要介绍C语言的相关知识&#xff0c;思路以下面的参考链接教程为主&#xff0c;大部分笔记也出自该教程。除了参考下面的链接教程以外&#xff0c;笔者还参考了其它的一些C语言教材&#xff0c;笔者认为重要的部分大多都会用粗体标注&#xf…

升级Xcode 15-全程绿灯+高速公路

还没升级Xcode15的兄弟们&#xff0c;恭喜你们&#xff0c;看完这篇文章&#xff0c;让你的升级Xcode15 之路畅通无阻外加全程高速&#x1f60e;。 前提 系统要求&#xff1a;MacOS 13.5 或更高版本 系统没达到要求的兄弟&#xff0c;先下载好系统升级包&#xff0c;下载好了…

设计模式——2_4 中介者(Mediator)

我寄愁心与明月&#xff0c;随风直到夜郎西 ——李白《闻王昌龄左迁龙标遥有此寄》 文章目录 定义图纸一个例子&#xff1a;怎么调度一组地铁站台和地铁开车指挥中心 碎碎念中介者和表单平台思想但是这种平台便利性是要付出代价的变化隔离原则 姑妄言之 定义 用一个中介者对象…

抖店月销过万的爆单技巧,新手轻松月入1w+,附抖店学习资料!

我是电商珠珠 抖店开通之后&#xff0c;怎么才能快速出单是很多新手小伙伴困扰的问题。其实想要运营好抖店一点都不难&#xff0c;我做抖店也有三年多时间了&#xff0c;接下来我说的每一步&#xff0c;不管是有货源还是无货源的都适用。 1、铺货低价福利款 店铺开好之后&am…

ABAP 因去重和汇总导致金额数值错误

在去重之前&#xff0c;就有两条重复的&#xff0c;一旦进行分组汇总&#xff0c;金额就会翻倍&#xff0c;之后又进行去重&#xff0c;也是没有用的&#xff0c;错误数据是2588.6&#xff0c;是1294.3的两倍&#xff0c;现在试试先去重&#xff0c;再去计算数据 就是因为去重…

JAVA虚拟机实战篇之内存调优[4](内存溢出问题案例)

文章目录 版权声明修复问题内存溢出问题分类 分页查询文章接口的内存溢出问题背景解决思路问题根源解决思路 Mybatis导致的内存溢出问题背景问题根源解决思路 导出大文件内存溢出问题背景问题根源解决思路 ThreadLocal占用大量内存问题背景问题根源解决思路 文章内容审核接口的…