Redis:常用数据结构 单线程模型

🌈 个人主页:Zfox_
🔥 系列专栏:Redis

🔥 常用数据结构
🐳 Redis 当中常用的数据结构如下所示:
Redis 在底层实现上述数据结构的过程中,会在源码的角度上对于上述的内容进行特定的优化,这样的优化的主要目的是为了实现出节省时间和节省空间的效果,具体的优化方法当然还是要看的是具体的内容
Redis 在外部承诺,对于哈希表来说,保证用户在进行增删查改这些操作都能保证是O(1),但是具体内部的实现来说,其实并不是一个传统意义的哈希表,在特定的实现场景下会使用其他的数据结构来实现,但是总体上来说,还是能够保证时间复杂度是满足具体的要求的
所以我们说,对于 Redis 内部的数据结构或者说是数据类型来说,这是 Redis 承诺给用户的,但是在其内部的实现中,可能会不同,具体的方式是有编码方式来进行决定的,因此换句话说,对于同一个数据结构来说,内部会有不同的实现方式,在不同的场景下会使用不同的方式,但是作为上层的使用者,其实是感知不到这样的存在的
那么下面我将会进行分析,不同的数据结构内部代表的意义是什么,以及是如何进行场景优化的
🦋 Redis 的编码方式
string
先说 string 类型,这个类型并不陌生,就是一个字符串类型,在内部编码的角度来讲:
- 如果采用的是 raw,表示的是最基本的字符串,它的底层就是一个 char 的数组
- 而如果采用的是 int 的编码方式,则对应的场景可能是要使用一些类似于计数的功能,那么此时作为 Value 值,其实使用传统意义的字符是没有意义的,直接使用整数int来保存是一个更好的解决方案
- 如果采用的是 embstr,则表示的是针对于短字符串进行的特殊优化,这里就不再过多描述
hash
- hash 这种数据类型,或者说是数据结构,是有两种编码方式的,第一种是 hashtable,这种实现方式就是最基本的实现方式,Redis 内部也是用这种最基本的方式来实现的,虽然这里的实现方式和前面的不太一样,但是也大体思维差不多
- 而对于一些元素比较少的时候,如果还使用哈希表其实是没有意义的,因此就会把对应的编码方式更换为 ziplist,它的主要目的可以进行列表的压缩,这样可以节省空间
🦋 压缩的意义?
那到此,可能会关心的问题是,为什么要进行压缩?意义在哪呢?因为 Redis 内部是有很多的 key 值的,这就意味着对于某些 key 的 Value 是一个 hash,所以当 key 值比较多的时候,对应的 hash 结构也会比较多,但是每一个 hash 的实际占用其实不大,因此就可以选择去尽量的压缩,这样压缩后就可以使得整体上的占用变的比较少了
list
对于list来说,有两种实现的方式,一种是 linkedlist,也就是传统意义上的 list,而另外一个表示的是压缩列表,但是从 Redis 3.2 开始,采用的是一个全新的方式,叫做 quicklist,它可以综合前面的两种类型,这样就针对于空间和效率折中进行实现的
set
对于 set 来说,也有两种实现,第一个是传统意义的实现,第二个表示的是 intset,如果都是使用的 int 类型的数据,那么内部就会选择这种情况
zset
- skipset,是跳表,每个节点上有多个指针域,可以快速定位到类型,最终使得搜索效果完成到二叉搜索树的效果,这里不再赘述,前面的内容中已经有对应的策略~
- ziplist:压缩
查看方式
object encoding xxx
Redis 内部,会通过具体的实际情况来调整内部的编码方式,自动进行适应
🔥 单线程架构
Redis
使⽤了单线程架构来实现⾼性能的内存数据库服务,本节⾸先通过多个客户端命令调⽤的例⼦说明Redis
单线程命令处理机制,接着分析Redis
单线程模型为什么性能如此之⾼,最终给出为什么理解单线程模型是使⽤和运维Redis
的关键。
Redis
只使用一个线程处理所有的命令请求,不是说一个 Redis
服务器进程内部真的就只有一个线程其实也有多个线程, 多个线程是在处理 网络 IO
🦋 引出单线程模型
现在开启了三个redis-cli客户端同时执⾏命令。
127.0.0.1:6379> set counter 1
客户端2对counter做⾃增操作:
127.0.0.1:6379> incr counter
客户端3对counter做⾃增操作:
127.0.0.1:6379> incr counter
客户端1设置⼀个字符串键值对:我们已经知道从客⼾端发送的命令经历了:发送命令、执⾏命令、返回结果三个阶段,其中我们重点关注第2步。我们所谓的Redis是采⽤单线程模型执⾏命令的是指:虽然三个客⼾端看起来是同时要求Redis去执⾏命令的,但微观⻆度,这些命令还是采⽤线性⽅式去执⾏的,只是原则上命令的执⾏顺序是不确定的,但⼀定不会有两条命令被同步执⾏,如图2-3、2-4、2-5所⽰,可以想象Redis内部只有⼀个服务窗⼝,多个客⼾端按照它们达到的先后顺序被排队在窗⼝前,依次接受Redis的服务,所以两条incr命令⽆论执⾏顺序,结果⼀定 是2,不会发⽣并发问题,这个就是Redis的单线程执⾏模型。
Redis 能够使用 单线程模型 很好的工作, 原因主要在于 Redis 的核心业务逻辑,都是短平快的~~ 不太消耗 cpu 资源也就不太吃多核了!!!
弊端!!
Redis 必须要特别小心, 某个操作占用时间长, 就会阻塞其他命令的执行!
🦋 为什么单线程还能这么快
- 纯内存访问。Redis将所有数据放在内存中,内存的响应时⻓⼤约为100纳秒,这是Redis达到每秒万级别访问的重要基础。
- Redis 核心功能,比数据库的核心功能更简单,Redis 干的活少,提供的功能相比于 mysq 也是少了不少!
- ⾮阻塞IO。Redis使⽤epoll作为I/O多路复⽤技术的实现,再加上Redis⾃⾝的事件处理模型将epoll中的连接、读写、关闭都转换为事件,不在⽹络I/O上浪费过多的时间
- 单线程避免了线程切换和竞态产⽣的消耗。单线程可以简化数据结构和算法的实现,让程序模型更简单;其次单线程避免了在线程竞争同⼀份共享数据时带来的切换和等待消耗
🦋 弊端
虽然单线程给Redis带来很多好处,但还是有⼀个致命的问题:对于单个命令的执⾏时间都是有要求的。如果某个命令执⾏过⻓,会导致其他命令全部处于等待队列中,迟迟等不到响应,造成客户端的阻塞
,对于Redis这种⾼性能的服务来说是⾮常严重的,所以Redis是⾯向快速执⾏场景的数据库
🔥 共勉
😋 以上就是我对 Redis:常用数据结构 & 单线程模型
的理解, 觉得这篇博客对你有帮助的,可以点赞收藏关注支持一波~ 😉
相关文章:

Redis:常用数据结构 单线程模型
🌈 个人主页:Zfox_ 🔥 系列专栏:Redis 🔥 常用数据结构 🐳 Redis 当中常用的数据结构如下所示: Redis 在底层实现上述数据结构的过程中,会在源码的角度上对于上述的内容进行特定的…...

夏普比率(Sharpe ratio)
具有投资常识的人都明白,投资光看收益是不够的,还要看承受的风险,也就是收益风险比。 夏普比率描述的正是这个概念,即每承受一单位的总风险,会产生多少超额的报酬。 用数学公式描述就是: 其中࿱…...

【优选算法】模拟 问题算法
一:替换所有的问号 class Solution { public:string modifyString(string s) {int n s.size();for(int i 0; i < n; i){if(s[i] ?){for(char ch a; ch < z; ch){if((i0 && ch !s[i1]) || (in-1 && ch ! s[i-1]) || ( i>0 &&…...

Flask+LayUI开发手记(八):通用封面缩略图上传实现
前一节做了头像上传的程序,应该说,这个程序编写和操作都相当繁琐,实际上,头像这种缩略图在很多功能中都会用到,屏幕界面有限,绝不会给那么大空间摆开那么大一个界面,更可能的处理,就…...

低代码采购系统搭建:鲸采云+能源行业订单管理自动化案例
在能源行业数字化转型浪潮下,某大型能源集团通过鲸采云低代码平台,仅用3周时间就完成了采购订单管理系统的定制化搭建。本文将揭秘这一成功案例的实施路径与关键成效。 项目背景与挑战 该企业面临: 供应商分散:200供应商使用不同…...

android关于pthread的使用过程
文章目录 简介代码流程pthread使用hello_test.cppAndroid.bp 编译过程报错处理验证过程 简介 android开发经常需要使用pthread来编写代码实现相关的业务需求 代码流程 pthread使用 需要查询某个linux函数的方法使用,可以使用man 函数名 // $ man pthread_crea…...
Faiss vs Milvus 深度对比:向量数据库技术选型指南
Faiss vs Milvus 深度对比:向量数据库技术选型指南 引言:向量数据库的时代抉择 在AI应用爆发的今天,企业和开发者面临着如何存储和检索海量向量数据的重大技术选择。作为当前最受关注的两大解决方案,Faiss和Milvus代表了两种不同…...
慢慢欣赏linux 之 last = switch_to(prev, next)分析
last switch_to(prev, next); 为什么需要定义last作为调用switch_to之前的prev的引用 原因如下: struct task_struct * switch_to(struct task_struct *prev,struct task_struct *next) {... ...return cpu_switch_to(prev, next);> .global cpu_switch_tocpu_…...

如何用 HTML 展示计算机代码
原文:如何用 HTML 展示计算机代码 | w3cschool笔记 (请勿将文章标记为付费!!!!) 在编程学习和文档编写过程中,清晰地展示代码是一项关键技能。HTML 作为网页开发的基础语言&#x…...

2025年ESWA SCI1区TOP,自适应学习粒子群算法AEPSO+动态周期调节灰色模型,深度解析+性能实测
目录 1.摘要2.粒子群算法PSO原理3.改进策略4.结果展示5.参考文献6.代码获取7.算法辅导应用定制读者交流 1.摘要 能源数据的科学预测对于能源行业决策和国家经济发展具有重要意义,尤其是短期能源预测,其精度直接影响经济运行效率。为了更好地提高预测模型…...

LeetCode - 53. 最大子数组和
目录 题目 Kadane 算法核心思想 Kadane 算法的步骤分析 读者可能的错误写法 正确的写法 题目 53. 最大子数组和 - 力扣(LeetCode) Kadane 算法核心思想 定义状态变量: currentSum: 表示以当前元素为结束的子数组的最大和。 maxSum: 记录全局最大…...
稻米分类和病害检测数据集(猫脸码客第237期)
稻米分类图像数据集:驱动农业智能化发展的核心资源 引言 在全球农业体系中,稻米作为最关键的粮食作物之一,其品种多样性为人类饮食提供了丰富选择。然而,传统稻米分类方法高度依赖人工经验,存在效率低、主观性强等缺…...
DOM(文档对象模型)深度解析
DOM(文档对象模型)深度解析 DOM 是 HTML/XML 文档的树形结构表示,提供了一套让 JavaScript 动态操作网页内容、结构和样式的接口。 一、DOM 核心概念 1. 节点(Node)类型 类型值说明示例ELEMENT_NODE1元素节点<div>, <p>TEXT_NODE3文本节点元素内的文字COMMEN…...
四、Sqoop 导入表数据子集
作者:IvanCodes 日期:2025年6月4日 专栏:Sqoop教程 当不需要将关系型数据库中的整个表一次性导入,而是只需要表中的一部分数据时,Sqoop 提供了多种方式来实现数据子集的导入。这通常通过过滤条件或选择特定列来完成。 …...

【读代码】从预训练到后训练:解锁语言模型推理潜能——Xiaomi MiMo项目深度解析
项目开源地址:https://github.com/XiaomiMiMo/MiMo 一、基本介绍 Xiaomi MiMo是小米公司开源的7B参数规模语言模型系列,专为复杂推理任务设计。项目包含基础模型(MiMo-7B-Base)、监督微调模型(MiMo-7B-SFT)和强化学习模型(MiMo-7B-RL)等多个版本。其核心创新在于通过…...

DROPP算法详解:专为时间序列和空间数据优化的PCA降维方案
DROPP (Dimensionality Reduction for Ordered Points via PCA) 是一种专门针对有序数据的降维方法。本文将详细介绍该算法的理论基础、实现步骤以及在降维任务中的具体应用。 在现代数据分析中,高维数据集普遍存在特征数量庞大的问题。这种高维特性不仅增加了计算…...
DeepSeek11-Ollama + Open WebUI 搭建本地 RAG 知识库全流程指南
🛠️ Ollama Open WebUI 搭建本地 RAG 知识库全流程指南 💻 一、环境准备 # 1. 安装 Docker 和 Docker Compose sudo apt update && sudo apt install docker.io docker-compose -y# 2. 添加用户到 docker 组(避免 sudo 权限&…...
【AI大模型】Transformer架构到底是什么?
引言 —— 想象一台能瞬间读懂整本《战争与和平》、精准翻译俳句中的禅意、甚至为你的设计草图生成前端代码的机器——这一切并非科幻,而是过去七年AI领域最震撼的技术革命:Transformer架构创造的奇迹。 当谷歌在2017年揭开Transformer的神秘面纱时&…...
code-server安装使用,并配置frp反射域名访问
为什么使用 code-server是VSCode网页版开发软件,可以在浏览器访问编程,可以使用vscode中的插件。如果有自己的服务器,使用frp透传后,域名访问在线编程,使用方便,打开的服务端口不需要单独配置,可…...

MTK-Android12-13 Camera2 设置默认视频画质功能实现
MTK-Android12-13 Camera2 设置默认视频画质功能实现 场景:部分客户使用自己的mipi相机安装到我们主板上,最大分辨率为1280720,但是视频画质默认的是640480。实际场景中,在默认视频分辨率情况下拍出来的视频比较模糊、预览也不清晰…...
Kafka 消息模式实战:从简单队列到流处理(一)
一、Kafka 简介 ** Kafka 是一种分布式的、基于发布 / 订阅的消息系统,由 LinkedIn 公司开发,并于 2011 年开源,后来成为 Apache 基金会的顶级项目。它最初的设计目标是处理 LinkedIn 公司的海量数据,如用户活动跟踪、消息传递和…...

Linux知识回顾总结----进程状态
本章将会介绍进程的一些概念:冯诺伊曼体系结构、进程是什么,怎么用、怎么表现得、进程空间地址、物理地址、虚拟地址、为什么存在进程空间地址、如何感性得去理解进程空间地址、环境变量是如何使用的。 目录 1. 冯诺伊曼体系结构 1.1 是什么 1.2 结论 …...

Linux 进程管理学习指南:架构、计划与关键问题全解
Linux 进程管理学习指南:架构、计划与关键问题全解 本文面向初学者,旨在帮助你从架构视角理解 Linux 进程管理子系统,构建系统化学习路径,并通过结构化笔记方法与典型问题总结,夯实基础、明确方向,逐步掌握…...
【异常】极端事件的概率衰减方式(指数幂律衰减)
在日常事件中,极端事件的概率衰减方式并非单一模式,而是取决于具体情境和数据生成机制。以下是科学依据和不同衰减形式的分析: 1. 指数衰减(Exponential Decay) 典型场景:当事件服从高斯分布(正态分布)或指数分布时,极端事件的概率呈指数衰减。 数学形式:概率密度函数…...

Git 使用大全:从入门到精通
Git 是目前最流行的分布式版本控制系统,被广泛应用于软件开发中。本文将全面介绍 Git 的各种功能和使用方法,包含大量代码示例和实践建议。 文章目录 Git 基础概念版本控制系统Git 的特点Git 的三个区域Git 文件状态 Git 安装与配置安装 GitLinuxmacOSWi…...

奈飞工厂官网,国内Netflix影视在线看|中文网页电脑版入口
奈飞工厂是一个专注于提供免费Netflix影视资源的在线播放平台,致力于为国内用户提供的Netflix热门影视内容。该平台的资源与Netflix官网基本同步,涵盖电影、电视剧、动漫和综艺等多个领域。奈飞工厂的界面简洁流畅,资源分类清晰,方…...

Python基于蒙特卡罗方法实现投资组合风险管理的VaR与ES模型项目实战
说明:这是一个机器学习实战项目(附带数据代码文档),如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融投资中,风险管理是确保资产安全和实现稳健收益的关键环节。随着市场波动性的增加,传统…...
【bat win系统自动运行脚本-双击启动docker及其它】
win系统自动化运行脚本 创建一个 startup.bat右键编辑,输入以下示例 echo off start "" "C:\Program Files\Docker\Docker\Docker Desktop.exe"timeout /t 5docker start your_container_namestart cmd /k "conda activate your_conda_e…...
SpringBoot离线应用的5种实现方式
在当今高度依赖网络的环境中,离线应用的价值日益凸显。无论是在网络不稳定的区域运行的现场系统,还是需要在断网环境下使用的企业内部应用,具备离线工作能力已成为许多应用的必备特性。 本文将介绍基于SpringBoot实现离线应用的5种不同方式。…...
js 比较两个对象的值,不相等就push对象的key
在JavaScript中,比较两个对象(object)的值并找出不相等的key,可以通过多种方法实现。下面是一些常用的方法: 方法1:使用JSON.stringify 这种方法适用于简单的对象,其中对象的值是基本类型或可…...