Redis 底层数据结构

• 简单动态字符串

• 链表

• 字典

• 跳跃表

• 整数集合

• 压缩列表

• 对象

SDS

增加了len和free属性,记录buf数组的使用空间和剩余空间。好处:strken函数直接读取len值,时间复杂度是O(1);预分配buf长度,避免频繁申请内存空间。分配规则,每次申请的free和len一样,最大额外申请1MB空间。

链表

由list和listNode两个数据结构组成。list记录了head、tail和len,表示链头、链尾和长度。listNode是一个双端节点,包含prev、next和value。

字典

由字典、哈希表、哈希表节点组成。字典记录了元素类型、两个哈希表和rehash标识。哈希表记录了节点数组、数组长度、节点数量。哈希表节点记录了key、value和next指针。value是一个复合结构,可以是指针或者整型数字。

哈希表扩缩容是通过rehash实现。开始rehash时,字典表启用另一个哈希表,容量是原来的两倍。再将原来的数据rehash过去。

为了避免一次性迁移太多数据,通过渐渐式hash。在key被更新、删除、查询的时候才做rehash。直到所有key都迁移完成,再把老的哈希表清空。

Rehash触发的条件,在非bgsave或bgrewriteaof时,容量因子大于1就开始执行。在bgsave或bgrewriteaof期间,容量因子要大于5才开始执行。避免期间rehash产生额外的内存,影响子进程的效率。

跳跃表

是有序集合的底层实现之一,由跳跃表和跳跃表节点组成。跳跃表包含头节点、尾节点和链表长度属性。跳跃表节点包含层级数组(跨度、前进指针)、后退指针、分数和obj组成。

节点排序规则是按分数从小到大排列,分数相同按照obj的字典顺序排列。

跳跃表和平衡数的区别是,跳跃表查询复杂度平均跟平衡树一样是logn,最差是n²,但是它的实现很简单。

整数集合

是集合的底层实现之一,当集合里只包含整数时,会使用这个结构。包含编码类型、长度和元素数组组成。编码类型包括int16、int32、int64,元素数组里的类型和编码类型相同。

当新元素比元素数组里存放的类型比大时,会进行类型升级,重新分配空间和排序。升级的好处是能节约空间,并且可以灵活存放不同类型的数据。只会升级不会降级。

压缩列表

是列表和哈希表底层的实现之一,当只包含数字和短的字符串时,使用这个结构。由压缩列表和节点构成。压缩链表包含字节大小、尾指针偏移量、节点个数、节点列表、结束标识。压缩节点包含上个节点的长度、编码类型和节点值。

上个节点的长度是动态的,分为1字节和5字节。上个节点的字节长度大于254时,升级到5字节。

对象

包含字符串、列表、哈希、集合和有序集合五种对象类型。

字符串由int、embstr和raw构成,占用空间从小到大,

列表由压缩列表和链表组成,元素少的时候用压缩列表。空间紧凑,节约内存。

哈希由压缩列表和字典组成,使用压缩列表主要也是省空间。

集合由整型数组和哈希组成。元素少的时候,就用整型数组,空间利用率高。

有序集合由压缩列表和跳表加字典的组成。跳表时候范围查询,字典适合单值查询。

相关推荐
摇滚侠17 分钟前
Redis 秒杀功能 超卖问题 一人一单问题 分布式锁 精彩!精彩!
redis·分布式·bootstrap
Emily呀5 小时前
【无标题】
redis
愈努力俞幸运6 小时前
function calling与mcp
android·数据库·redis
IronMurphy6 小时前
Redis拷打第一讲
数据库·redis·缓存
楠枬7 小时前
Redis 事务
数据库·redis·缓存
摇滚侠9 小时前
Redis 查询接口加缓存 缓存雪崩 缓存穿透 缓存击穿 精彩!精彩!
redis·缓存
Mr. zhihao9 小时前
[特殊字符] 从 Redis 缓存穿透到布隆过滤器,再到布谷鸟过滤器:一次穿透防护的进化之旅
数据库·redis·缓存
@小匠9 小时前
Redis 7 持久化机制
数据库·redis·缓存
phltxy10 小时前
Redis 核心数据类型之 String 详解
数据库·redis·bootstrap
码哥字节11 小时前
开多个 Agent 后 Claude Code 账单翻了 4 倍,一个配置解决了
redis·性能