浅谈单线程的Redis快的原因是什么

单线程 Redis 如此之快的 4 个原因 作为内存中数据存储,Redis 以其速度和性能着称,通常被用作大多数后端服务的缓存解决方案。但是,在内部,Redis 采用单线程架构。为什么单线程设计依然会有这么高的性能?如果利用多线程并发处理请求不是更好吗?在本文中,让我们深入探讨为什么 Redis 才有单线程架构,依然如此之快,主要从下面4个方面讲解。内存数据存储优良的数据结构单线程架构非阻塞IO让我们一一剖析。综上所述,单线程架构是Redis团队经过时间考验的深思熟虑的选择。 阅读详情

前言

我们都知道Redis很快,我们还总是听别人说Redis是单线程的,那么单线程的Redis为什么那么快呢?

1. Redis单线程的本质

其实,Redis并不是单线程,我们之所以会一直称Redis是单线程,这是因为Redis在处理客户端的读写请求时,只有一个主线程,而在处理以下这些操作时,Redis会fork出其他的子线程来处理:

  • 主从数据同步

  • 切片集群数据同步

  • 过期键值异步删除

  • AOF或RDB持久化

所以整体来看Redis并不是单线程。

在Redis6.0中引入的多线程机制,实际上只是将网络IO读写处理这块逻辑变成多线程,因为在Redis6.0以前的版本中, 网络IO请求也是在主线程中进行处理,随着互联网应用的高并发访问以及网络硬件性能的提升,在主线程中进行网络IO处理已经成为Redis的瓶颈,因此使用多线程来处理网络IO请求,可以显示提高Redis响应速度,而对于键值对的读写,仍然由主线程一个线程进行处理,这样可以仍然可以不用加锁也能保证读写操作的原子性,避免多线程互斥机制带来的性能损耗。

2. 单线程为什么那么快?

通过前面的介绍,我们知道,Redis并非完全是单线程,但在处理网络IO和数据读写等Redis核心功能时,Redis确实是由主线程处理的,那么我们就不禁有个疑问,Redis的单线程为什么那么快呢?

总结了以下大概有以下四个方面的原因:

  • 内存操作

  • 高效的底层数据结构

  • 多路复用IO模型

  • 避免多线程切换开销

2.1 内存操作

Redis是内存数据库,读写操作都在内存中,学过计算机基础的我们都知道,CPU读取内存的速度要比读取磁盘的速度快得多,所以单台Redis服务器每秒能处理数十万的读取也就不足为怪了,事实上,基于内存的读写操作,是Redis能这么快的最重要的原因。

​

2.2 高效的底层数据结构

我们都知道Redis提供了五种非常好用的数据类型:String,List,Hash,Set,Sorted Set。

Redis有六种底层数据结构,分别为哈希表,压缩列表,跳表,整数数组,简单动态字符串。

数据类型与其底层数据结构对应关系如下图所示

​

总结来说就是:

  • String:Redis没有使用C语言内置的字符数组,而是将字符数组封装为简单动态字符串(SDS),虽然SDS比C语言原生字符数组更费内存,但通过空间换时间,可以将很多C语言字符数组时间复杂度为O(n)的操作转为O(1),提高处理速度,比如strlen命令获取String长度时,对于C语言的字符数组,需要遍历数组才能知道,时间复杂度为O(n),而简单动态字符串已经保存了字符串的长度,因此可以直接获取,时间复杂度为O(1)。

  • Hash:在数据量还不多的情况下,Hash类型使用压缩列表(ZipList)保存元素,因为元素不多,所以查找也比较快,如果数据增长到设定的值,就改为哈希表,而哈希表查找元素的时间复杂度为O(1),所以也是相当快的。

  • List:List的底层数据结构为双向链表和压缩列表组合而成的,也称为快速链表(QuickList),因此List类型非常适合头尾插入弹出的操作,因此如果要把Redis作为队列的话,选择List是非常高效的。

  • Sorted Set:当元素数量不多时,Sorted Set使用的是压缩列表,只有当元素超过设定值时,才使用跳表和哈希表。

  • Set:在元素的数值都是整数时,Set使用整数数组保存数据,如果元素数量达到设置的值,则改为哈希表。

Redis是一个Key-Value健值对数据库,我们上面介绍的五种类型是指Key-Value中的Value,对于所有Key到Value之间的映射,Redis也是采用哈希表,这个哈希表也叫全局哈希表,如下图所示:

​

2.3 多路复用IO模型

Redis高性能的另一个重要的原因是采用多路复用IO模型,由于Redis是单线程处理网络请求的,如果采用阻塞IO模型,那么对于每一个请求,Redis需要从接收连接->读取连接数据->处理命令->返回数据整个流程处理完成后才能处理处理下一个请求,如果是这样的话,那么Redis的快就无从谈起了。

而采用非阻塞模型IO,虽然可以避免阻塞,但这种模型会在内核空间与用户空间来回复制全部要监听的FD(文件描述符),除了之外,我们还无法得知哪个FD已经就绪了,需要遍历所有的FD才能知道,同样是即费空间又费时间,因此对于需要支持高并发的Redis来说,显然也是不可接受的。

而多路复用IO模型则不同了,多路复用IO模型同样也是非阻塞的,其内置的红黑树可以高效地添加或查找FD,且只会将已经就绪的的FD从内核空间复制到用户空间,因此很多网络应用处理请求时都是使用多路复用IO模型,Redis也不例外。

多路复用IO模型在不同的操作系统有不同的实现,如selec和poll,还有更性能更好的epoll,Redis不同操作系统的多路复用IO模型都有封装。

2.4 避免多线程切换

因为将数据保存在内存中,并且有高效的数据结构和使用多路利用IO模型,所以Redis读取数据非常快速,这时候,你可能会想,是不是将Redis改为多线程,可以更好提升Redis的吞吐量,处理更多并发请求呢?

其实不然,正因为Redis读取非常快,所以如果采用多线程的话,会产生以下两个问题:

  • 多线程切换带来的额外开销:因为Redis读写非常快速,因为如果采用多线程,那么线程切换就非常频繁,所以如果采用多线程的话,Redis大部分时间可能都在切换线程。

  • 数据加锁的性能损耗:多线程访问同一个数据的话,为了避免竞争,肯定需要加锁保证数据操作的原子性,而加锁与等待锁的释放,让多个线程在读取同一个数据需要排队等待,所以效率并不比单线程强多少。

3 怎么让Redis更快

单台Redis服务器,已经非常快了,那么,有什么办法能让Redis更快呢?

  • 使用AOF或RDB数据备份:有了数据备份,可以在服务器宕机时,更快地恢复

  • 主从分离:让从服务器分担主服务器的压力,实现更快地响应

  • 切片集群:除了主从,切片集群让数据分散到不同服务器,多台服务器可分担读写的压力

  • 避免bigkey:bigkey是指键值过大或者集合元素过多,占用太多的带宽与CPU运算,导致主线程阻塞,所以要避免在Redis存储比较大的值,比如对于value来说,不要超过10KB,对于集合元素,元素的数量最好不要超过1000

4 小结

从上面的分析我们可以看,Redis并不是像我们认为的是单线程,在处理持久化等耗时任务时,Redis也是采用多线程的处理方式,不过,Redis在处理请求时只有一个主线程,但仍然做非常快速的响应,这是由于Redis的数据读写都在内存中,而内存的访问是非常快速的,另外Redis为每一种数据类型都精心设计了高效的底层数据结构,而在处理网络请求时,则采用基于多路复用的IO模型,使得Redis可以高并地处理更多的请求。

Redis是单线程的,但Redis为什么这么快? Redis之所以能在单线程模型下保持高性能,主要得益于其基于内存存储、单线程模型、C语言开发、高效的数据结构和算法以及异步非阻塞I/O模型等多个方面的优势。这些优势使得Redis在处理大量并发请求时能够保持快速响应和高吞吐量。 阅读详情

相关推荐

单线程的Redis为什么这么快

单线程的Redis为什么这么快?

weixin_68286174的博客 926

Redis 单线程为什么速度这么快

Redis 单线程为什么速度这么快

Raphael的博客 1498

Redis高阶篇之Redis单线程与多线程

之前写过关于Redis的十篇文章,关于Redis快的原因是单线程执行指令和IO多路复用比较笼统,所以打算单开一篇文章深入介绍Redis单线程与多线程。以及Redis不同版本的多线程和IO多路复用情况。Redis自身出道就是优秀,基于内存操作、数据结构简单、多路复用和非阻塞I/O、避免了不必要的线程上下文切换等特性,在单线程的环境下依然很快;

qq_39126115的博客 1759

为什么单线程的Redis那么快?

从上面的分析我们可以看,Redis并不是像我们认为的是单线程,在处理持久化等耗时任务时,Redis也是采用多线程的处理方式,不过,Redis在处理请求时只有一个主线程,但仍然做非常快速的响应,这是由于Redis的数据读写都在内存中,而内存的访问是非常快速的,另外Redis为每一种数据类型都精心设计了高效的底层数据结构,而在处理网络请求时,则采用基于多路复用的IO模型,使得Redis可以高并地处理更多的请求。,由于Redis是单线程处理网络请求的,如果采用阻塞IO模型,那么对于每一个请求,Redis需要从。

Huangjiazhen711的博客 624

Wincc7.5SP1 按钮操作记录(二次确认及语音播报)

Wincc 7.5 SP1 按钮操作记录生成(含二次确认及语音播报) 前面一篇文章已经介绍了“语音播报WINCC报警”,本文是之前功能的延伸,记录按钮操作记录并实现播报。 操作记录及语音播报效果 <创建消息文本> 1. 创建消息文本 消息编号100,消息等级“系统无确认”,消息类型“操作员输入消息”,消息文本“循环水泵启动操作”,其他参数默认。 消息编号101,消息等级“系

徐站的春天 1万+

Doorbell机制在PCI与MSI中断中的高效应用

本文深入解析了Doorbell机制在PCIe设备与CPU间通信中的核心作用。作为一种高效的硬件通知机制,它通过内存映射I/O(MMIO)实现软件对硬件的轻量级触发,常与MSI中断协同工作,构建高效的生产者-消费者模型。文章以AMD GPU的Ring Buffer命令提交为例,阐述了该机制如何显著降低CPU开销、提升系统吞吐量,并对比了其与传统中断方式的性能优势。

ee345的博客 610

【Redis】高级篇: 一篇文章讲清楚Redis的单线程和多线程

一种同步的IO模型,实现一个线程监视多个文件句柄,一旦某个文件句柄就绪,就能通知到对应程序进行相应的读写操作,没有文件句柄就绪时,就会阻塞应用程序,从而释放CPU资源。I/O网络I/O,尤其在操作系统层面指数据在内核态和用户态之间的读写操作多路多个客户端连接(连接就是套接字描述符,即socket或者channel)复用复用一个或者几个线程连接IO多路复用也就是说一个或者一组线程处理多个TCP,使用单进程就能实现同时处理多个客户端的连接,无需创建或者维护过多的进程/线程总结。

aqin1012的博客 4640

深入理解Redis(一)----Redis简介+Redis为什么这么快

Redis是一个开源的内存中的数据结构存储系统,它可以用作:数据库、缓存和消息中间件。

qq_24428851的博客 3860

Android图形系统(三)系统篇:渲染/合成的底层原理浅析

众所周知,渲染工作是由GPU负责,那么在聊GPU之前首先得知道什么是“渲染”?我们来举个例子感受一下在系统中申请一块10*101、把图层背景这玩意染成绿的2、从左上(0,0)到右下(10,10)画一条宽度为1颜色为红色的直线3、以坐标点(5,5)为中心,画一个半径为3的实心圆,颜色要蓝色好了,接下来操作系统会把这些“绘图指令”同步给GPU去执行渲染任务图片来源:自己画的GPU完成渲染工作后,我们将会得到一个大小为10*10二维数组,数组中的每个元素都保存着坐标点的颜色信息、深度信息。

1358

【DeepSeek开发入门】DeepSeek API 开发初体验

在人工智能蓬勃发展的时代,DeepSeek作为一款功能强大的AI大模型,为开发者提供了丰富的接口和便捷的开发体验。本文将基于DeepSeek的几个关键接口,带你快速入门,开启DeepSeek开发的探索之旅。通过本文,你已经初步了解了DeepSeek开发中几个重要接口的使用方法,包括列出模型、对话补全和查询余额接口,以及开发过程中的常见问题及解决办法。这是你踏入DeepSeek开发领域的第一步。在后续的学习中,你可以深入研究模型的参数调优,探索不同模型在各种场景下的应用,如利用模型实现更复杂的推理对话功能。

寻道AI,探索AI无限可能! 2764

Redis系列-1.Redis浅谈

模拟一个tcp服务器处理30个客户socket。第一种选择(轮询):按顺序逐个验收,先验收A,然后是B,之后是C、D。。。这中间如果有一个学生卡住,全班都会被耽误,你用循环挨个处理socket,根本不具有并发能力。第二种选择(来一个new一个,1对1服务):你创建30个分身线程,每个分身线程检查一个学生的答案是否正确。这种类似于为每一个用户创建一个进程或者线程处理连接。第三种选择(响应式处理,1对多服务),你站在讲台上等,谁解答完谁举手。

爱吃知识的土豆倪的博客 1540

Vue3 - 详细实现微信公众号H5网页内置浏览器中预览下载word文档(doc)、excel表格(xls)、ppt文稿、pdf文档等文件,微信内部直接打开预览和下载到本地教程,安卓苹果手机无差异兼容

vue3,nuxt3,微信公众号,h5,移动端,网页,网站,vue微信内置浏览器下载文件,下载文件,在微信浏览器里面实现下载任意文件,H5需要在微信浏览器中下载excel文件,实现网页在微信内置浏览器中下载文件详细教程,安卓点击下载会提示打开浏览器,后端返回流文件,如何解决无法下载文件,跳转至浏览器下载文件,发送到电脑微信,安卓,苹果,手机系统,微信H5页面,vue3微信公众号H5网站,内置浏览器下载文档,如何在微信浏览器中预览office文件,word文档,excel文档,pdf文档,ppt文档,offi

🏆 前端领域优质创作者 1万+

【Redis】浅谈数据结构和内部编码和单线程架构

type 命令实际返回的就是当前键的数据结构类型,它们分别是:string(字符串)、list(列表)、hash(哈希)、set(集合)、zset(有序集合),但这些只是 Redis 对外的数据结构,当然Redis可不只这5种数据结构,大概有10种。我们介绍最常用的,如图所示:实际上 Redis 针对每种数据结构都有自已的底层内部编码实现,而且是多种实现,这样 Redis 会在合适的场景选择合适的内部编码,目的就是为了达到节省时间/空间的效果!

2401_83251330的博客 776

基于Python的Steam游戏评论与销量数据爬取及预测分析

随着数字游戏市场的蓬勃发展,Steam作为全球最大的数字游戏分发平台,积累了海量的游戏数据与玩家行为数据。本文旨在通过Python网络爬虫技术,采集Steam平台的游戏基本信息、玩家评论数据及销量相关信息,为后续的游戏评论情感分析与销量预测模型构建提供数据支持。本文将详细介绍使用requestsselenium等库实现Steam数据爬取的全过程,并提供完整的代码实现与数据处理方法。关键词:Steam;Python爬虫;数据采集;评论分析;销量预测。

2201_76125261的博客 855

Android SurfaceFlinger——概述(一)

对于系统渲染流程的理解是指导 SurfaceFlinger 设计的核心思想,从 Android 4.1 一直到 Android 9.0 都没有太大的变化。只要抓住这五个核心思想,我们阅读 SurfaceFlinger 的难度就会下降不少。下面看一下 SurfaceFlinger 的体系和 Skia 以及 View的绘制流程的关系。framework 面向开发者所有的 View 是便于开发的控件,里面仅仅只是提供了当前 View 各种属性以及功能。

小旭的专栏 2584

Redis(高阶篇)01章——单线程 VS 多线程(入门篇)

Redis(高阶篇)01章——单线程 VS 多线程(入门篇)

weixin_74019079的博客 733

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

Redis的单线程模型,以及Redis为什么这么快!!!

Redis的单线程模型保证了redis不会出现线程安全问题但也会有一定的弊端; redis速度快的四大原因,经典面试题; 浅谈IO多路复用机制;

he20021221的博客 273

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

【Redis】全局命令/内部编码/浅谈单线程模型

Redis常用的全局命令、数据结构内部编码、单线程模型。

qq_55119554的博客 1120

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

浅谈Redis(一)

Redis是一个开源的内存数据结构存储系统,可以用作数据库、缓存和消息中间件。Redis支持多种数据结构,比如string、hash、list、set及sorted set等。无论是本地缓存还是分布式缓存,为了保证高性能,都采用内存保存数据,由于成本和内存限制,当存储的数据超过缓存容量时,需要对缓存的数据进行剔除。

快乐江小鱼的博客 1276

浅谈redis

一、什么是Redis Redis是一个key-value存储系统,现在在各种系统中的使用越来越多,大部分情况下是因为其高性能的特性,被当做缓存使用,这里介绍下Redis经常遇到的使用场景 二、Redis特性 读写性能优异 持久化 数据类型丰富 单线程 数据自动过期 发布订阅 分布式 三、Redis应用场景 1.缓存 缓存是Redis最常见的应用场景,之所有这么使用,主要是因为Redis读写性能优异。而且逐渐有取代memcached,成为首选服务端缓存的组件。而且,Redis内部是支持事务的,在使用时候能有效

幽谷虫师 4168

redis

应用场景有

weixin_45931856的博客 3333

浅谈Redis

Redis 为什么响应快 ①数据保存在内存中 Redis 数据保存在内存中,读写操作只要访问内存,不需要磁盘 IO。 ②底层数据结构 如下: Redis 的数据以 key:value 的格式存储在散列表中,时间复杂度 o(1)。 Redis 为 value 定义了丰富的数据结构,包括动态字符串、双向链表、压缩列表、hash、跳表和整数数组,可以根据 value 的特性选择选择最高效的数据结构。 ③单线程模型 Redis 的网络 IO 和数据读...

shiyuezhong的专栏 294

浅谈Redis原理

浅谈Redis原理前言性能为什么单线程模型也能效率这么高工作原理文件事件处理器(file event handler)线程模型I/O模型阻塞I/O非阻塞I/OIO 多路复用selectpollepoll 前言 众所周知,redis是单线程,性能极高,处理速度极快。单机的redis已经可以扛起上万的QPS,集群模式下,可以支撑十万级别的读写并发。为什么redis性能这么快,下面我们一起来探究一下 性能 为什么单线程模型也能效率这么高 纯内存操作 核心是基于非阻塞的IO多路复用机制 单线程避免了多线程的频繁上

butt168的博客 244

浅谈Redis网络模型

Redis 是C语言开发的一个开源高性能键值对的内存数据库,也是一种NoSQL(not-only sql,非关系型数据库)的数据库,可以用来做数据库、缓存、消息中间件等场景。在目前的技术选型中,Redis常常被用来作为数据缓存和分布式锁的解决方案。Redis具有以下几个特点,分别是高性能,多种数据结构,支持持久化,分布式等等:1)高性能:Redis是基于内存的数据存储系统,可以实现高速读写操作,适合用作数据缓存和高速读写的存储系统。

weixin_43907032的博客 739
上一篇: 有关MYSQL的22年最新部分面试题汇总
下一篇: 可以随意设置redis缓冲区的大小吗?
Java_LingFeng
博客等级 码龄4年 505粉丝 259原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值