Redis快的原因
1、基于内存实现

Redis将所有数据存储在内存中,因此它可以非常快速地读取和写入数据,而无需像传统数据库那样将数据从磁盘读取和写入磁盘,这样也就不受I/O限制。
2、I/O多路复用
多路指的是多个socket连接;复用指的是复用一个线程。多路复用主要有三种技术:select、 poll、epoll。epoll是最新的也是目前最好的多路复用技术。Redis使用IO多路复用的原理图如下所示:

Redis内核会一直监听socket上的连接请求,一旦有请求到达就交给Redis线程处理,这就实现了一个Redis线程处理多个IO流的效果。
Redis线程不会阻塞在某一个特定的客户端请求处理上,所以Redis可以同时和多个客户端连接并处理请求。select/epoll提供了基于事件的回调机制,即针对不同事件的发生,调用相应的事件处理器,因此Redis一直在处理事件,提升了Redis 的响应性能。
3、高效的数据结构
Redis中有多种数据类型,每种数据类型的底层都由一种或多种数据结构来支持。正是因为有了这些数据结构,所以大大的提升了Redis存储与读取速度。下图整理了Redis中常见数据类型与底层的数据结构:

3.1 简单动态字符串
Redis的字符串类型底层使用的是简单动态字符串(SDS),它是用来处理字符串的,C语言中用到SDS来处理字符串,C语言中的字符串展示如下图所示:

想要获取字符串“REDIS”的长度,需要从头开始遍历,直到遇到 ‘\0’ 为止。Redis是C语言实现的,那么Redis中字符串是怎么使用SDS的呢?如下图所示:

Redis中用一个len字段记录当前字符串的长度,想要获取长度只需要获取len字段即可。
Redis中SDS修改及空间扩充时,除了分配所必须的空间外,还会额外分配未使用的空间。具体的操作是如果len长度小于1M,那么将会额外分配与len相同长度的未使用空间,如果修改后长度大于1M,那么将分配1M 的使用空间。
Redis中存在惰性的空间释放,即是SDS缩短时并不会回收多余的内存空间,而是使用free字段将多出来的空间记录下来。如果后续有变更操作,直接使用 free中记录的空间,减少了内存的分配。
3.2 双端链表
Redis的List数据结构更多是被当作队列或栈来使用的,队列和栈的特性一个先进先出,一个先进后出,那么使用双端链表很好实现这些特性,双端链表的如下图所示:

头节点里同时还有一个参数len,用来记录链表长度的,因此获取链表长度时不用再遍历整个链表,直接拿到len值就可以了,这个时间复杂度是 O(1)。
3.3 压缩链表
如果在双端链表中,一个链表节点中存储一个小数据(如一个字节)。那么对应的就要保存头节点,前后指针等额外的数据,这样就浪费了空间,同时由于反复申请与释放操作也容易导致内存碎片化,内存的使用效率就太低了,于是就出现了压缩链表,如下图所示:

压缩列表的内存是连续分配的,遍历的速度很快。
3.4 跳跃表
Redis中跳跃表是在链表的基础上增加了多级索引来提升查找效率。如下图所示的跳跃表原理图:

跳跃表每一层都有一条有序的链表,最底层的链表包含了所有的元素。这样跳跃表就可以支持在 O(logN) 的时间复杂度里查找到对应的节点。
在Redis中跳表真实的存储结构是在头节点里记录了相应的信息,减少了一些不必要的系统开销,如下图所示:

3.5 hashTable
哈希表本质上是一个数组,每一个元素叫做哈希桶,每个桶中的entry保存着键值指针(key和value)。Redis其实就是一个全局哈希表,哈希表的时间复杂度是O(1),通过key的哈希值和哈希函数,就可以定位对应哈希桶的位置,从而确定桶中entry,然后找到对应数据,如下如所示

Redis中存储的数据越来越多的时候,会出现哈希冲突,所以Redis采用链式哈希的方式解决冲突,即同一个桶里面的元素使用链表保存,如下图所示:

随着数据量的增加,哈希冲突越来越多,链表也随之越来越长,进而导致查找性能变差。因此Redis使用了两个全局哈希表,通过rehash操作,增加现有的哈希桶数量,分散单桶元素数量,从而在减少哈希冲突的同时缩短链表长度,提高Redis的查询效率。
4、单线程模型
Redis的单线程指的是Redis的网络IO及键值对指令读写是由一个线程来执行的,对于Redis的持久化、集群数据同步、异步删除等都是其他线程执行。
因为Redis是基于内存的操作,CPU不是Redis的瓶颈,Redis的瓶颈最有可能是机器内存的大小或者网络带宽。Redis使用单线程的优势如下所示:
(1)不会因为线程创建导致的性能消耗
(2)避免上下文切换引起的CPU消耗,没有多线程切换的开销
(3)避免了线程之间的竞争问题,比如添加锁、释放锁、死锁等,不需要考虑各种锁问题。
5、合理的数据编码
对于每一种数据类型来说,底层的支持可能是多种数据结构,什么时候使用哪种数据结构,这就涉及到了编码转化的问题。Redis中不同的数据类型是如何进行编码转化,如下所示:
(1)String:存储数字时候采用 int类型的编码,如果是非数字的话,采用raw编码。
(2)List:字符串长度及元素个数小于一定范围使用ziplist编码,任意条件不满足,则转化为linkedlist编码。
(3)Hash:hash对象保存的键值对内的键和值字符串长度小于一定值及键值对。
(4)Set:保存元素为整数及元素个数小于一定范围使用intset编码,任意条件不满足,则使用hashtable编码。
(5)Zset:zset对象中保存的元素个数小于及成员长度小于一定值使用 ziplist编码,任意条件不满足,则使用skiplist编码。
相关文章:
Redis快的原因
1、基于内存实现 Redis将所有数据存储在内存中,因此它可以非常快速地读取和写入数据,而无需像传统数据库那样将数据从磁盘读取和写入磁盘,这样也就不受I/O限制。 2、I/O多路复用 多路指的是多个socket连接;复用指的是复用一个线…...
Android 自己的智能指针
在 Android 系统中,强指针模板类(sp<T>) 是一种基于引用计数的智能指针实现,专门用于管理对象的生命周期。它被广泛用于 Android Framework 的底层(Native 层/C 代码),尤其是与 Binder 通…...
如何在React中集成 PDF.js?构建支持打印下载的PDF阅读器详解
本文深入解析基于 React 和 PDF.js 构建 PDF 查看器的实现方案,该组件支持 PDF 渲染、图片打印和下载功能,并包含完整的加载状态与错误处理机制。 完整代码在最后 一个PDF 文件: https://mozilla.github.io/pdf.js/web/compressed.tracemo…...
【完美解决】VSCode连接HPC节点,已配置密钥却还是提示需要输入密码
目录 问题描述软件版本原因分析错误逻辑链 解决方案总结 问题描述 本人在使用 VSCode Remote-SSH 插件连接超算集群节点时,遇到以下问题:已正确配置 SSH 密钥,且 VSCode 能识别密钥文件(如图1),但在…...
智能DNS解析:解决高防IP地区访问异常的实战指南
摘要:针对高防IP在部分地区无法访问的问题,本文设计基于智能DNS的流量调度方案,提供GeoDNS配置与故障切换代码示例。 一、问题背景 运营商误拦截或线路波动可能导致高防IP在福建、江苏等地访问异常。传统切换方案成本高,智能DNS可…...
【JSON2WEB】16 login.html 登录密码加密传输
【JSON2WEB】系列目录 【JSON2WEB】01 WEB管理信息系统架构设计 【JSON2WEB】02 JSON2WEB初步UI设计 【JSON2WEB】03 go的模板包html/template的使用 【JSON2WEB】04 amis低代码前端框架介绍 【JSON2WEB】05 前端开发三件套 HTML CSS JavaScript 速成 【JSON2WEB】06 JSO…...
ruby超高级语法
以下是 Ruby 中一些 极度硬核 的语法和底层特性,涉及元编程的深渊、虚拟机原理、语法黑魔法等,适用于追求极限的 Ruby 开发者: 高级语法一 一、语法核弹级操作 1. 动态修改继承链 class A; def foo; "A"; end end class B; def …...
第十二天 - Flask/Django基础 - REST API开发 - 练习:运维管理后台API
从零开始用Flask/Django构建运维管理后台API(实战指南) 前言:为什么选择Python Web框架? 在运维自动化领域,构建管理后台是每个运维工程师的必修课。本文将通过Flask和Django两个主流框架,手把手教你构建…...
Docker 容器内运行程序的性能开销
在 Docker 容器内运行程序通常会有一定的性能开销,但具体损失多少取决于多个因素。以下是详细分析: 1. CPU 性能 理论开销:容器直接共享宿主机的内核,CPU 调度由宿主机管理,因此 CPU 运算性能几乎与原生环境一致&…...
从递归入手一维动态规划
从递归入手一维动态规划 1. 509. 斐波那契数 1.1 思路 递归 F(i) F(i-1) F(i-2) 每个点都往下展开两个分支,时间复杂度为 O(2n) 。 在上图中我们可以看到 F(6) F(5) F(4)。 计算 F(6) 的时候已经展开计算过 F(5)了。而在计算 F(7)的时候,还需要…...
【2025年认证杯数学中国数学建模网络挑战赛】A题解题思路与模型代码
【2025年认证杯数学建模挑战赛】A题 该题为典型的空间几何建模轨道动力学建模预测问题。 ⚙ 问题一:利用多个天文台的同步观测,确定小行星与地球的相对距离 问题分析 已知若干地面天文台的观测数据:方位角 (Azimuth) 和 高度角 (Altitude)&…...
蓝桥杯备赛 Day16 单调数据结构
单调栈和单调队列能够动态的维护,还需用1-2两个数组在循环时从单调栈和单调队列中记录答案 单调栈 要点 1.时刻保持内部元素具有单调性质的栈(先进后出),核心是:入栈时逐个删除所有"更差的点",一般可分为单调递减栈、单调递增栈、单调不减栈、单调不增…...
轻量级爬虫框架Feapder入门:快速搭建企业级数据管道
一、目标与前置知识 1. 目标概述 本教程的主要目标是: 介绍轻量级爬虫框架 Feapder 的基本使用方式。快速搭建一个采集豆瓣电影数据的爬虫,通过电影名称查找对应的电影详情页并提取相关信息(电影名称、导演、演员、剧情简介、评分…...
golang gmp模型分析
思维导图: 1. 发展过程 思维导图: 在单机时代是没有多线程、多进程、协程这些概念的。早期的操作系统都是顺序执行 单进程的缺点有: 单一执行流程、计算机只能一个任务一个任务进行处理进程阻塞所带来的CPU时间的浪费 处于对CPU资源的利用&…...
深入理解Java Optional:告别NullPointerException的优雅方式
大家好!今天我们来聊聊Java 8引入的一个超实用类 - Optional。不是那个让你重启电脑的CtrlAltDel哦!😄 这是一个能让我们优雅处理null值的工具类,彻底告别烦人的NullPointerException! 一、为什么需要Optional&#x…...
【算法竞赛】树上最长公共路径前缀(蓝桥杯2024真题·团建·超详细解析)
目录 一、题目 二、思路 1. 问题转化:同步DFS走树 2. 优化:同步DFS匹配 3. 状态设计:dfs参数含义 4. 匹配过程:用 map 建立权值索引 5. 终止条件:无法匹配则更新答案 6. 总结 三、完整代码 四、知识点总…...
【windows10】基于SSH反向隧道公网ip端口实现远程桌面
【windows10】基于SSH反向隧道公网ip端口实现远程桌面 1.背景2.SSH反向隧道3.远程连接电脑 1.背景 Windows 10远程桌面协议的简称是RDP(Remote Desktop Protocol)。 RDP是一种网络协议,允许用户远程访问和操作另一台计算机。 远程桌面功…...
Python----概率论与统计(贝叶斯,朴素贝叶斯 )
一、贝叶斯 1.1、贝叶斯定理 贝叶斯定理(Bayes Theorem)也称贝叶斯公式,是关于随机事件的条件概率的定理 贝叶斯的的作用:根据已知的概率来更新事件的概率。 1.2、定理内容 提示: 贝叶斯定理是“由果溯因”的推断&…...
NO.88十六届蓝桥杯备战|动态规划-多重背包|摆花(C++)
多重背包 多重背包问题有两种解法: 按照背包问题的常规分析⽅式,仿照完全背包,第三维枚举使⽤的个数;利⽤⼆进制可以表⽰⼀定范围内整数的性质,转化成01 背包问题。 ⼩建议:并不是所有的多重背包问题都能…...
vue项目打包里面pubilc里的 tinymce里的js文件问题
以下是解决 Vue 项目打包后 public/tinymce 中 JS 文件路径问题的完整方案: 问题原因 当使用 public 目录存放静态资源时,Vue CLI 默认会将 public 下的文件 直接复制到打包目录的根路径,但以下操作可能导致路径错误: 开发环境使…...
Python星球日记 - 第18天:小游戏开发(猜数字游戏)
🌟引言: 上一篇:Python星球日记 - 第17天:数据可视化 名人说:路漫漫其修远兮,吾将上下而求索。(屈原《离骚》) 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 目录 一、游戏概述与原理1. 游戏基本规则2. 编程知识点3.猜数字游戏流程图二、游戏逻辑设计…...
爬虫抓包工具和PyExeJs模块
我们在处理一些网站的时候, 会遇到一些屏蔽F12, 以及只要按出浏览器的开发者工具就会关闭甚至死机的现象. 在遇到这类网站的时候. 我们可以使用抓包工具把页面上屏蔽开发者工具的代码给干掉. Fiddler和Charles 这两款工具是非常优秀的抓包工具. 他们可以监听到我们计算机上所…...
无人机击落技术难点与要点分析!
一、技术难点 1. 目标探测与识别 小型化和低空飞行:现代无人机体积小、飞行高度低(尤其在城市或复杂地形中),雷达和光学传感器难以有效探测。 隐身技术:部分高端无人机采用吸波材料或低可探测设计,进…...
2025年Java无服务器架构实战:AWS Lambda与Spring Cloud Function深度整合
摘要 📝 本文深入探讨如何在2025年Java生态中实现AWS Lambda与Spring Cloud Function的无缝整合。我们将从基础概念讲起,逐步深入到实际部署、性能优化和最佳实践,通过详实的代码示例展示如何构建高效、可扩展的无服务器Java应用。 目录 &a…...
LeetCode 题目 「二叉树的右视图」 中,如何从「中间存储」到「一步到位」实现代码的优化?
背景简介 在 LeetCode 的经典题目 「二叉树的右视图」 中,我们需要返回从右侧看一棵二叉树时所能看到的节点集合。每一层我们只能看到最右边的那个节点。 最初,我采用了一个常规思路:层序遍历 每层单独保存节点值 最后提取每层最后一个节…...
8.第二阶段x64游戏实战-string类
免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动! 本次游戏没法给 内容参考于:微尘网络安全 上一个内容:7.第二阶段x64游戏实战-分析人物属性 string类是字符串类,在计算机中…...
Go语言sync.Mutex包源码解读
互斥锁sync.Mutex是在并发程序中对共享资源进行访问控制的主要手段,对此Go语言提供了非常简单易用的机制。sync.Mutex为结构体类型,对外暴露Lock()、Unlock()、TryLock()三种方法,分别用于阻塞加锁、解锁、非阻塞加锁操作(加锁失败…...
C++实现文件断点续传:原理剖析与实战指南
文件传输示意图 一、断点续传的核心价值 1.1 大文件传输的痛点分析 网络闪断导致重复传输:平均重试3-5次。 传输进度不可回溯:用户无法查看历史进度。 带宽利用率低下:每次中断需从头开始。 1.2 断点续传技术优势 指标传统传输断点续传…...
MySQL中FIND_IN_SET函数与INSTR函数用法解析
一、功能定义与语法 1、FIND_IN_SET函数 语法:FIND_IN_SET(str, strlist) 功能:在逗号分隔的字符串列表(strlist)中查找精确匹配的子字符串(str),并返回其位置(从1开始)…...
Python贝叶斯回归、强化学习分析医疗健康数据拟合截断删失数据与参数估计3实例
全文链接:https://tecdat.cn/?p41391 在当今数据驱动的时代,数据科学家面临着处理各种复杂数据和构建有效模型的挑战。本专题合集聚焦于有序分类变量处理、截断与删失数据回归分析以及强化学习模型拟合等多个重要且具有挑战性的数据分析场景,…...
