Redis常用数据结构及其底层实现

Redis常用数据结构

主要有

String List Set Zset Hash BitMap Hyperloglog Stream Geo

String:

Redis最常用的一种数据结构,Sting类型的数据存储结构有三种int、embstr、raw

1.int:用来存储long以下的整形

embstr raw 都是用来存字符串,其中小于44字节的字符串用embstr存 大于的用raw存

二者的底层都用的SDS(简单动态字符串) 底层就是一个char[]+length+free

相比c语言自己的字符串 有几个优势

1. 获取字符长度不用再遍历字符,直接返回length

2. 可以动态扩缩容,不会出现缓冲区溢出,扩容时会多分配一些(预分配策略),缩容时只是用free记录空闲的长度

3. 二进制安全(c语言遇到\0时会认为字符串结束)

embstr会把redisObject相关的结构和sds存在一块连续的内存空间 节省内存

raw 是分开存储

List

在redis3.2之前,redis存list是通过ziplist+linkedlist 3.2之后用的是quicklist

3.2之前:

当元素个数较少(<512且每个元素的长度小于64字节)时  用ziplist(压缩列表)

用一整块连续内存存所有的数据,与普通数组不同的是,每个节点所占的空间并不相同,而是用多少占多数,这样更加紧凑,减少内存碎片,但是也会有一些问题

问题:1.随机访问性能差、由于每个节点的内存都不一样 所以难以随机访问

          2.可能触发连锁更新:节点中要存之前节点的长度,若是插入较大的元素,则可能引发级联更新(后面的元素更新pre_length 又导致后续的节点触发更新)

linkedlist:就是个双向链表

3.2之后:quicklist:每个节点都是一个ziplist 降低了级联更新产生的影响 也保证了空间上的紧凑性

redis7之后所有的ziplist都被替换成listpack(每个节点都只记录自己的长度)

Hash

在数据个数较少时 直接用的ziplist/listpack 压根没用hash 就是按keyvalue keyvalue 紧凑存储

获取数据时压根没用哈希 而是遍历的

说是在数据量较少时 用这种紧凑的结构 即使线性遍历 可能也比哈希快 

在数据量超过某个阈值后,会用ziplist/listpack +hashtable的结构

一个字典包括两个dict(渐进式hash用的)

扩容机制:有负载因子=已保存节点的数量/哈希表的大小 大于等于1时 若没有生成rdb或重写aof会扩容  大于5时 不管怎么样立马扩容 小于0.1时会进行缩容

渐进式rehash:哈希表在进行扩容时会一点一点扩容,而不是一次性扩容,当需要扩容时会先把rehash标记设为0,然后生成一个两倍原来大小的表,然后对原有表的增删改查会一步一步把数据迁移到新表,当迁移完毕后再移动指针

Set

底层有两种实现 HashTableIntSet(有序整数集合,且元素个数小于512,通过二分查找查找元素)

ZSet

底层是大名鼎鼎的跳表 我感觉本质上就是带了多层索引的双向链表

查询的时间复杂度是logn 添加或删除元素也是logn

新增元素时每层按0.5的概率决定该层是否增加该节点的索引

查询时自上向下 一直缩小要查询的节点所在的范围

为什么不用红黑树?

1.红黑树实现复杂、难以维护

2.红黑树要实现范围查询要回溯

为什么不用B+树?

1.B+树节点占用空间大

2.B+树插入节点可能要分裂 比较复杂

3.B+树主要是为了减少树高、减少io查询  redis不需要

BitMap

就是一个位图,是一串连续的二进制数 用偏移量来定位

redis的底层 bitmap是一个char[] 在c语言中 char是一个字节 即八个比特位

用位访问的方式set某位置元素为0或1

index + pos  index代表位置第几个char上  index表示在该index内 是第几位

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

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

相关文章

O3.4 opencv图形拼接+答题卡识别

一图形拼接逻辑导入必要的库pythonimport cv2 import numpy as np import sys导入cv2库用于图像处理&#xff0c;numpy库用于数值计算&#xff0c;sys库用于与 Python 解释器进行交互&#xff0c;例如退出程序。定义图像显示函数def cv_show(name, img):cv2.imshow(name, img)c…

SQL注入常见攻击点与防御详解

SQL注入是一种非常常见且危险的Web安全漏洞。攻击者通过将恶意的SQL代码插入到应用程序的输入参数中&#xff0c;欺骗后端数据库执行这些非预期的命令&#xff0c;从而可能窃取、篡改、删除数据或获得更高的系统权限。以下是详细、准确的SQL注入点分类、说明及举例&#xff1a;…

EKSPod 资源利用率配置修复:从占位符到完整资源分析系统

概述 在 Kubernetes 集群管理过程中,资源利用率的监控和优化是保证应用性能和成本效益的关键环节。近期,我们对 EKSPod 管理界面的资源利用率显示功能进行了全面修复,将原先简单的占位符文本升级为完整的资源分析系统。本文将详细介绍这次修复的背景、方案、实现细节和最终…

Linux内核(架构)

文章目录Linux内核架构概述核心子系统详解1、进程管理2、内存管理3、虚拟文件系统(VFS)4、设备驱动模型掌握Linux内核核心技术阶段1&#xff1a;基础准备阶段2&#xff1a;内核基础阶段3&#xff1a;深入子系统阶段4&#xff1a;高级主题&#xff08;持续学习&#xff09;调试和…

基于数据挖掘的单纯冠心病与冠心病合并糖尿病的证治规律对比研究

标题:基于数据挖掘的单纯冠心病与冠心病合并糖尿病的证治规律对比研究内容:1.摘要 背景&#xff1a;冠心病和冠心病合并糖尿病在临床上较为常见&#xff0c;且二者在证治方面可能存在差异&#xff0c;但目前相关系统研究较少。目的&#xff1a;对比基于数据挖掘的单纯冠心病与冠…

即梦AI快速P图

原图&#xff1a; 模型选择3.0效果比较好&#xff0c;提示词“根据提供图片&#xff0c;要求把两边脸变小&#xff0c;要求把脸变尖&#xff0c;要求眼妆变淡&#xff0c;眼睛更有神&#xff0c;要求提亮面部肤色要求面部均匀&#xff0c;面部要磨皮!鼻头高光和鼻翼两边阴影变淡…

【办公类-109-04】20250913圆牌卡片(接送卡被子卡床卡入园卡_word编辑单面)

背景需求: 为了发被子,我做了全校批量的圆形挂牌,可以绑在“被子包”提手上,便于再操场上发放被子时,很多老师可以协助根据学号发放。 https://blog.csdn.net/reasonsummer/article/details/149755556?spm=1011.2415.3001.5331https://blog.csdn.net/reasonsummer/arti…

Shoptnt 促销计算引擎详解:策略模式与责任链的完美融合

在电商系统中&#xff0c;促销计算是业务逻辑最复杂、变更最频繁的模块之一。它不仅需要处理多种促销类型&#xff08;满减、折扣、优惠券等&#xff09;&#xff0c;还要管理它们之间的优先级和互斥关系。 Shoptnt 设计了一套基于 策略模式 (Strategy Pattern) 和 责任链模式…

【HTTP 请求格式】从请求行 到 请求体

引言 在前后端开发中&#xff0c;前端和后端之间的交互主要依赖于 HTTP&#xff08;HyperText Transfer Protocol&#xff0c;超文本传输协议&#xff09;。HTTP 是互联网通信的基础&#xff0c;它定义了客户端&#xff08;通常是浏览器或App&#xff09;和服务器之间如何交换数…

【自记】SQL 中 GROUPING 和 GROUPING SETS 语句的案例说明

我们用一个生活中的例子来理解&#xff0c;比如你开了家小超市&#xff0c;想统计「销售额」&#xff0c;但需要从多个角度看&#xff08;比如按 “日期 商品”、“仅日期”、“仅商品”、“整体总销售额”&#xff09;。假设你的销售数据长这样&#xff08;简化版&#xff09…

C语言第五课:if、else 、if else if else 控制语句

C语言第五课&#xff1a;if、else 、if else if else 控制语句if else 、if else if else 联合使用编程快速学习平台if else 、if else if else 联合使用 代码示列 #include <stdio.h> int main(){//设置中文编码输出到控制台system("chcp 65001");//今天星…

七彩喜智慧养老:用科技温暖晚年,让关爱永不掉线

“当银发潮遇见科技力&#xff0c;养老方式正在发生一场静悄悄的变革。”你有没有想过&#xff1a;当父母年迈独居时&#xff0c;如何确保他们的安全&#xff1f;当老人突然摔倒&#xff0c;如何第一时间获得救助&#xff1f;当慢性病需要长期管理&#xff0c;如何避免频繁奔波…

window显示驱动开发—为头装载和专用监视器生成自定义合成器应用(二)

显示相关的 API 的比较 API用途和目标受众DisplayInformation用于检索 CoreWindow 的呈现和布局属性。HdmiDisplayInformation用于枚举和设置受限模式集的仅限 Xbox 的 API。 高度专用于 Xbox 媒体应用方案。DisplayMonitor用于查询物理监视器设备的属性。 不公开有关操作系统…

Linux 高性能 I/O 事件通知机制的核心系统调用—— `epoll_ctl`

epoll 是 Linux 上处理大量文件描述符 I/O 事件的高效模型&#xff0c;而 epoll_ctl 则是你用来指挥 epoll 实例&#xff08;epoll instance&#xff09;的“遥控器”&#xff0c;负责向它添加、修改或删除需要监视的文件描述符&#xff08;FD&#xff09;及其感兴趣的事件。1.…

mysql 必须在逗号分隔字符串和JSON字段之间二选一,怎么选

如果必须在逗号分隔字符串和JSON字段之间二选一&#xff0c;那么 JSON字段是明显更好的选择。以下是详细的对比分析&#xff1a;对比结论&#xff08;直接看这里&#xff09;方面JSON字段逗号分隔字符串胜出方查询能力✅ 丰富的JSON函数支持❌ 只能使用LIKE模糊查询JSON数据验证…

DPI和DIP的区别

DPI 和 DIP 是两个在计算机图形和移动开发领域常见的术语&#xff0c;它们都与屏幕显示和尺寸有关&#xff0c;但含义和用途不同。 DPI (Dots Per Inch) 定义&#xff1a;DPI 的全称是 Dots Per Inch&#xff0c;即每英寸点数。它是一个衡量物理密度的单位&#xff0c;表示在…

数据帮助我们理解未知世界

主持人 尼古拉安根&#xff1a; 大家好&#xff0c;我是挪威南方财富基金首席执行官尼古拉安根。今天非常荣幸能与大卫斯皮格尔哈尔特爵士对话。坦率地说&#xff0c;他不仅是世界上最优秀的统计学家之一&#xff0c;也是我见过的最佳风险沟通者。他撰写了大量优秀著作&#xf…

在使用git的很多操作是保持工作区干净

这是一条铁律下面是错误操作&#xff1a;自己明明写完了代码&#xff0c;想要提交。此时你的工作区长这样你的提交顺序是&#xff1a;git pull -> git commit -> git push但是现实往往不这样&#xff0c;万一拉下来的代码和你当前工作区的代码有冲突&#xff0c;你必须要…

通过语法推导树快速求短语,简单短语和句柄

第一步&#xff1a;写出规范推导&#xff08;最右&#xff09;序列 规范推导就是最右推导。我们的目标是从起始符号 E 出发&#xff0c;通过每步替换最右边的非终结符&#xff0c;最终得到句型 R(Pi)。 文法 G[E]: E :: RP | PP :: (E) | iR :: RP | RP* | P | P* 推导过程&…

智能学习辅助系统-部门管理开发

文章目录准备工作工程搭建增删改查查询部门删除部门新增部门修改部门查询回显修改数据日志技术准备工作 需求&#xff1a;部门管理的查询、新增、修改、删除 使用REST风格的URL&#xff1a; GET &#xff1a; 查询POST &#xff1a;新增PUT &#xff1a; 修改DELETE &#x…