Redis 底层数据结构
Redis 底层数据结构
Redis 的高性能并非来自单一结构,而是通过多种针对场景高度定制的数据结构实现。上层五种数据类型(String / List / Hash / Set / ZSet)只是抽象接口,真正的性能边界由底层结构决定。
SDS(Simple Dynamic String)
基本原理
SDS 是 Redis 自定义的字符串实现,替代 C 原生 char*。其核心是显式维护字符串长度与剩余空间。
典型结构:
1 | struct sdshdr { |
核心特点
- O(1) 获取长度(避免
strlen) - 支持二进制数据(不依赖
\0作为字符串的结尾) - 预分配与惰性释放,减少内存重分配
- 避免缓冲区溢出
使用到的数据类型
- String
- 所有 key
- Hash / List / Set / ZSet 内部元素
时间复杂度
- 获取长度:O(1)
- 追加:均摊 O(1)
- 修改:O(n)
链表(Linked List)
基本原理
双向链表,每个节点独立分配内存,保存前后指针与值指针。
核心特点
- 双向
- 无环
- 表头表尾指针
- 节点值为
void*,类型无关
使用到的数据类型
- List(早期实现)
- 发布订阅消息队列
- 慢查询日志
- 客户端列表
时间复杂度
- 头尾插入 / 删除:O(1)
- 按值查找:O(n)
现状
已被 quicklist 取代作为 List 的主要实现。
压缩列表(ziplist)
基本原理
一段连续内存,通过偏移量描述节点,无指针。
每个 entry 包含:
- 前一个 entry 的长度
- 当前数据编码与长度
- 实际数据
核心特点
- 极致节省内存
- 顺序存储,CPU cache 友好
- 插入可能引发连锁更新
使用到的数据类型
- List(旧)
- Hash(小规模)
- ZSet(小规模)
时间复杂度
- 访问:O(n)
- 插入 / 删除:O(n)
现状
Redis 7 之前使用,已被 listpack 全面替代。
哈希表(Dict)
基本原理
标准 Hash Table + 链地址法,支持渐进式 rehash。
核心结构:
- 两张哈希表(ht[0], ht[1])
- rehash index
核心特点
- 扩容期间分批迁移
- 避免阻塞
- 支持自定义 hash 函数
使用到的数据类型
- Hash(大规模)
- Set
- ZSet(score 映射)
- 全局 key 空间
时间复杂度
- 查找 / 插入 / 删除:O(1) 平均,O(n) 最坏
- rehash:均摊 O(1)
整数集合(intset)
基本原理
用于存储仅包含整数的集合,底层为有序数组。
支持三种编码:
- int16_t
- int32_t
- int64_t(自动升级,不降级)
核心特点
- 内存占用极小
- 自动升级保证正确性
- 有序存储,二分查找
使用到的数据类型
- Set(所有元素为整数且数量较少)
时间复杂度
- 查找:O(log n)
- 插入 / 删除:O(n)
跳表(SkipList)
基本原理
多层链表结构,通过随机层级实现近似平衡。
核心特点
- 实现简单
- 范围查询高效
- 与哈希表组合使用
使用到的数据类型
- ZSet(按 score 排序)
ZSet 实际结构:
- Hash:member → score
- SkipList:按 score 排序
时间复杂度
- 查找 / 插入 / 删除:O(log n)
- 范围查询:O(log n + m)
quicklist
基本原理
链表 + ziplist/listpack 的混合结构。
- 外层:双向链表
- 内层:压缩列表(旧)或 listpack(新)
核心特点
- 降低指针开销
- 控制单块内存大小
- 平衡插入性能与内存效率
使用到的数据类型
- List(Redis 3.2+)
时间复杂度
- 头尾操作:O(1)
- 中间访问:O(n)
listpack
基本原理
ziplist 的重写版本,彻底解决连锁更新问题。
核心改进:
- 不再存储前一个 entry 的长度
- 更紧凑的编码设计
- 更明确的边界信息
核心特点
- 更安全
- 更易扩展
- 更适合大规模元素
使用到的数据类型
- List
- Hash
- ZSet
时间复杂度
- 访问 / 插入 / 删除:O(n)
- 实际性能优于 ziplist
总结
Redis 的设计逻辑明确:
- 小数据量 → 连续内存 → 节省内存
- 大数据量 → 复合结构 → 保证性能
- 写放大可接受,读路径必须稳定
理解这些底层结构,才能在以下问题上做出正确判断:
- key 设计
- value 结构选择
- 内存占用评估
- 性能瓶颈定位
Redis 的性能不是魔法,而是工程取舍的结果。




