Redis底层数据结构深度解析(基于Redis 7.2.5)

本文深入剖析Redis核心数据类型的底层实现机制,涵盖String、Hash、List、Set、Zset的实现原理及版本演进差异。

一、Redis数据存储核心机制

Redis所有数据以redisObject结构统一封装:

typedef struct redisObject {unsigned type:4;      // 数据类型(string, hash等)unsigned encoding:4;  // 底层编码(int, embstr等)unsigned lru:LRU_BITS; // 缓存淘汰策略信息int refcount;         // 引用计数void *ptr;            // 指向实际数据的指针
} robj;
  • 查看指令
    • TYPE key:返回数据类型
    • OBJECT ENCODING key:查看底层编码

二、String类型底层结构

三种编码方式:

  1. int编码
    • 条件:值为整数字符串(可转为long)
    • 特点:ptr直接存储整数值(省去指针开销)
  2. embstr编码
    • 条件:字符串长度 ≤ 44字节
    • 特点:内存连续分配,RedisObject与SDS共享内存
  3. raw编码
    • 条件:字符串长度 > 44字节
    • 特点:RedisObject与SDS分离存储

SDS(Simple Dynamic String)

动态字符串结构,解决C字符串缺陷:

struct __attribute__ ((__packed__)) sdshdr8 {uint8_t len;         // 已用长度uint8_t alloc;       // 总空间unsigned char flags; // 类型标识char buf[];          // 数据存储
};

优势:

  • O(1)复杂度获取长度
  • 二进制安全(允许存储\0
  • 预分配减少内存重分配

三、Hash类型底层结构

编码切换规则:

条件编码方式
所有键值对数量 ≤ hash-max-listpack-entries (默认512) 且 所有值长度 ≤ hash-max-listpack-value (默认64字节)listpack
任一条件不满足hashtable

Listpack(替代Redis6的ziplist)

连续内存结构解决ziplist连锁更新问题:

字段说明
total-bytes (4B)总字节数
num-elements (2B)元素数量
entry (变长)数据节点(每个键值对)
end-byte (1B)结束标识(0xFF)

节点结构

[编码类型][数据长度][实际数据]

→ 无需记录前驱节点长度,避免连锁更新


四、List类型底层结构

编码规则:

  • listpack编码:元素少且长度小
  • quicklist编码:元素多或长度大(默认切换阈值:list-max-listpack-size = -2 即8KB)

Quicklist结构

双向链表 + Listpack的复合结构:

typedef struct quicklist {quicklistNode *head;quicklistNode *tail;unsigned long count;     // 总元素数unsigned long len;       // 节点数...
} quicklist;typedef struct quicklistNode {struct quicklistNode *prev;struct quicklistNode *next;unsigned char *entry;    // 指向listpacksize_t sz;               // listpack字节大小...
} quicklistNode;

优势:

  • 链表结构:高效增删(O(1))
  • Listpack节点:内存连续,减少碎片

五、Set类型底层结构

编码切换规则:

条件编码方式
元素全为整数 & 元素数量 ≤ set-max-intset-entries (默认512)intset
元素数量 ≤ set-max-listpack-entries (默认128) 且 所有元素长度 ≤ set-max-listpack-value (默认64字节)listpack
任一条件不满足hashtable

Intset整数集合

typedef struct intset {uint32_t encoding;  // 编码方式(int16/int32/int64)uint32_t length;    // 元素数量int8_t contents[];  // 数据存储
} intset;

特点:元素有序存储,二分查找效率高


六、Zset类型底层结构

编码切换规则:

条件编码方式
元素数量 ≤ zset-max-listpack-entries (默认128) 且 所有值长度 ≤ zset-max-listpack-value (默认64字节)listpack
任一条件不满足skiplist

Skiplist跳表

多层索引结构实现高效查找:

typedef struct zskiplistNode {sds ele;                         // 元素值double score;                    // 分值struct zskiplistNode *backward;  // 后退指针struct zskiplistLevel {struct zskiplistNode *forward; // 前进指针unsigned long span;          // 跨度} level[];                       // 层级数组
} zskiplistNode;

性能

  • 查询/插入/删除:平均O(logN)
  • 空间复杂度:O(N)

七、Redis版本数据结构对比

数据类型Redis 6Redis 7
stringSDSSDS
hashziplist + hashtablelistpack + hashtable
listquicklist + ziplistquicklist + listpack
setintset + hashtableintset + listpack + hashtable
zsetziplist + skiplistlistpack + skiplist

关键演进:Redis 7使用listpack全面替代ziplist,彻底解决连锁更新问题。

附:Redis高性能核心要素

  1. 精细化数据结构:针对场景选择最优编码
  2. 内存连续存储:SDS/listpack利用CPU缓存
  3. 惰性删除:异步释放避免阻塞
  4. 单线程模型:无锁操作减少竞争
  5. IO多路复用:epoll/kqueue高效网络处理

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

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

相关文章

《C++初阶之STL》【auto关键字 + 范围for循环 + 迭代器】

【auto关键字 范围for循环 迭代器】目录前言:--------------- auto关键字 ---------------1. 什么是auto?2. 使用关键字auto时需要注意什么?3. 怎么使用auto关键字?--------------- 范围for循环 ---------------1. 什么是范围fo…

ionic 切换开关操作指南

ionic 切换开关操作指南 引言 在移动应用开发中,切换开关(Toggle)是一种常见的用户界面元素,它允许用户通过简单的操作来开启或关闭某个功能或设置。在Ionic框架中,切换开关提供了丰富的API和样式,使得开发…

【笔记记录-Linux文件权限与目录结构详解】

🌈个人主页: Aileen_0v0 🔥热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​💫个人格言:“没有罗马,那就自己创造罗马~” 文章目录目录结构解析Summarypart3part4part5目录结构解析 drwxr-xr-x 2 student student 4096 10月 8 2023…

【Complete Search】-基础完全搜索-Basic Complete Search

文章目录Solution - Maximum Distance涉及遍历整个解空间的问题资料-resources 6 - Complete Search 在很多问题中(尤其是在 USACO Bronze 级别),只需检查解空间中的所有可能情况就足够了,比如所有元素、所有元素对、所有子集&…

神经网络的层与块

什么是层?什么是块?在深度学习中,层(Layer) 和块(Block) 是构建神经网络的核心概念,尤其在 PyTorch、TensorFlow 等框架中,二者既紧密关联又有明确分工。理解它们的定义、…

如何用Qt写一个安卓Android应用

对于不会安卓开发的同胞来讲(比如我),想要做一个安卓应用(.apk)使用Qt是一个不错的方法,今天就来聊聊如何使用Qt结合C写一个安卓应用。 首先我们得拥有一个Qt,我使用的是5.14.2版本的,新版本可直接到qt官网去下载qt.io,老版本的现在qt官网不支…

泰语OCR识别技术方案

一、痛点分析1.1 泰语文字特性带来的挑战复杂字符集:泰语有44个辅音字母、15个元音符号、4个声调符号和10个数字,组合形式多样上下叠加结构:泰文字符常在垂直方向叠加组合,增加分割难度无词间空格:泰语单词间无明确分隔…

MER-Factory:多模态情感识别与推理数据集自动化工厂工具介绍

🛠️ 工具 如果这个项目对你有帮助,欢迎给 https://github.com/Lum1104/MER-Factory/ 仓库点一个 Star 🌟 ,这对我们帮助很大 MER-Factory 提供交互式工具来帮助您管理数据和配置处理流水线。 调优仪表板 调优仪表板 是一个基…

Python基础数据结构详解:字符串、列表、元组和字典的常用方法

目录 一、引言:为什么学习这些数据结构? 二、字符串(String)的常用方法 1. 基本操作 2. 查找索引 3. 大小写转换 4. 位置调整 5. 开头和结尾检查 6. 分割和连接 7. 删除空白字符 8. 类型判定 9. 替换内容 字符串小结 …

Liunx练习项目5.1-周期化任务;时间同步服务;

1.系统周期化任务1.1 at命令的用法at 时间 指定在规定的时间上执行相应的操作,完成操作crtlD完成编辑一分钟后输入的指令完成,创建了file{1..5}的文件at -l 查看系统上面所有用户的调度at -c 可以查看该任务的指令at -d 加编号可以删除该任务at -v 可以…

小皮面板搭建pikachu靶场

一、搭建所需的工具 1.下载小皮面板 下载地址为:小皮面板(phpstudy) - 让天下没有难配的服务器环境! 2.下载靶场所需的文件 下载地址为:https://github.com/zhuifengshaonianhanlu/pikachu 二、环境的搭建 打开小皮面板,使用所…

使用aiohttp实现高并发爬虫

使用aiohttp来编写一个高并发的爬虫,想法很不错,现实很骨感。这里我们要知道,由于高并发可能会对目标服务器造成压力,请确保遵守目标网站的robots.txt,并合理设置并发量,避免被封IP。 我将通过示例代码&…

【Linux庖丁解牛】— 信号量ipc管理!

1. 并发编程概念铺垫> 多个执行流【进程】看到同一份资源:共享资源。> 被保护起来的资源叫做临界资源。> 在进程中,涉及临界资源的程序段叫做临界区。【说人话就是程序中访问共享资源的代码】> 什么是互斥:任何时刻,只…

Spring Boot全局异常处理详解

原代码:package com.weiyu.exception;import com.weiyu.pojo.Result; import com.weiyu.utils.ErrorFileResponseUtils; import jakarta.servlet.http.HttpServletRequest; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; import …

FHE技术将彻底改变在线隐私保护方式

1. 在线隐私的简史 互联网刚刚诞生时,所有的内容都是未加密的。人们通过一个特定的地址访问网站,这个地址以“HTTP”开头。当时,这并不是什么大问题,因为人们在线访问的都是内容,而这些内容本身已经是公开的。但随着电…

Cursor配置Java环境、创建Spring Boot项目

一:配置JDK和Maven cursor默认会读取环境变量JAVA_HOME和MAVEN_HOME,如果没有配置去找默认路径~/.m2/settings.xml也可以手动指定:Ctrl Shift P 输入"Preferences:Open User Settings(JSON)"打开settings.json文件,然…

win11添加无线显示器(两个笔记本实现双屏)

前置条件: 两个笔记本要要支持无线显示器,支持蓝牙; 1、自己重装的win11系统,首先根据网上说明进去的时候,红色显示无无线投屏; 2、安装网上操作,查看自己电脑是否支持无线投屏(是支…

【MAC技巧】Bash/Zsh切换失败的故障排除

【MAC技巧】Bash/Zsh切换失败的故障排除 Troubleshooting to Failure " chsh: no changes made" By JacksonML 在Mac电脑中,终端(Terminal)是常用的命令行工具,对开发和运维至关重要。 依照苹果电脑的系统软件迭代,终端中存有B…

卷积神经网络-卷积的分类

卷积的定义卷积是图像处理中最核心的操作之一,其本质是通过卷积核(滤波器)与图像进行滑动窗口计算(像素值乘积之和),实现对图像特征的提取、增强或抑制。一、二维卷积--针对二维矩阵进行处理1.1单通道见得最…

全网首发:使用GIT下载时崩溃退出,是因为机械硬盘

前面有几篇文章,说是GIT下载会退出。开始以为是虚拟机问题。把家里的虚拟机复制到公司,照样崩溃。后来认为是内存不足。昨天在家里下载代码,也崩溃退出。心里觉得奇怪,试了一次,还是退出。差别在哪里?之前是…