Redis 数据结构

Redis 是如何通过数据结构设计,系统性地解决高性能状态访问问题的?


一、设计第一性原理:Redis 的世界观

在讨论具体数据结构之前,必须先明确 Redis 的设计前提。

1.1 核心约束条件(不变前提)

  1. 内存是第一稀缺资源Redis 是以内存为主的系统,任何设计都优先考虑内存占用。

  2. 访问延迟必须可预测且极低设计目标不是“吞吐最大化”,而是“单次访问足够快”。

  3. 大多数操作应为 O(1) 或接近 O(1)最坏情况可以存在,但不应成为常态路径。

  4. 系统应服务于真实访问模式,而非数据抽象的完美性Redis 的数据结构不是“学术最优”,而是“工程最优”。


1.2 Redis 的核心设计哲学

可以将 Redis 的设计哲学抽象为四句话:

后文的所有数据结构,都是这些哲学在不同场景下的具体体现。


二、Redis 不是“数据类型集合”,而是“访问模型集合”

传统视角下,我们常说 Redis 有五种数据类型:string、hash、list、set、zset。

但从架构视角看,更本质的划分是:

Redis 提供了一组“状态访问模型”,每种模型针对一种典型访问模式进行优化。

2.1 访问模型总览

访问模式主要诉求对应结构
单值快速访问极低延迟String
字段级随机访问O(1) 定位Hash
顺序写入 + 遍历插入频繁List / Quicklist
去重 + 集合运算成员唯一性Set
有序 + 范围查询排序与区间Sorted Set

这些结构并非彼此竞争,而是在不同约束条件下的最优解


三、String:最基础的状态单元

内部编码

3.1 本质抽象

String 是 Redis 中最小、最通用的状态表达单元

其本质并非“字符串”,而是:

一段二进制安全的字节序列(byte array)

Redis 不理解其语义,只负责高效存取。


3.2 支撑的访问模式

这些能力共同覆盖了:


3.3 关键设计权衡

这体现了 Redis 的核心哲学之一:

减少一次间接寻址,胜过任何微小算法优化


四、Hash:对象属性的状态映射

4.1 本质抽象

Hash 并不是“嵌套结构”,而是:

一个 key 下的多个子状态的并列存储

它解决的问题是:


4.2 工程意义

这使 Hash 成为:

的理想选择。


五、List / Quicklist:顺序状态的工程解

5.1 访问模型

List 服务的不是“数组”,而是:

高频插入 + 顺序遍历的状态序列

例如:


5.2 从 Ziplist 到 Quicklist 的演进

这一演进体现了 Redis 的工程哲学:

阶段优点暴露问题
Ziplist极省内存插入导致连锁更新
Quicklist分块隔离结构复杂
Listpack消除 prevlen编码复杂

本质规律:

当数据规模增长时,必须引入结构分层来隔离变化成本


六、Set:无序且唯一的状态集合

6.1 本质抽象

Set 表达的是:

“成员是否存在”这一布尔状态集合

而不是列表或映射。


6.2 典型价值

这些能力让 Set 成为推荐系统、标签系统的重要工具。


七、Sorted Set:有序状态与范围访问

7.1 本质抽象

Sorted Set 解决的是一个复杂但常见的问题:

在可排序的状态集合中,既要快速定位,又要高效范围查询


7.2 组合结构的哲学

ZSet 同时使用:

这是 Redis 中最经典的结构组合设计:

用不同结构分别优化不同访问路径


八、内部结构共性原则

无论是 SDS、dict、quicklist 还是 rax,它们都遵循相同原则:

  1. **连续内存优先**
  2. **元数据最小化**
  3. **渐进式变更(如 rehash)**
  4. **为常见路径优化,而非极端情况**

这些原则比任何具体实现都更值得被记住。


九、Redis 的职责边界与反例

9.1 Redis 能做什么

9.2 Redis 不适合什么

Redis 是“状态加速器”,而不是系统真相源。


十、可迁移的系统设计启示

  1. 数据结构是系统性能的第一生产力
  2. 延迟应被摊平,而不是集中爆发
  3. 不要为小概率牺牲高频路径
  4. 允许结构随规模演进
  5. 好的系统设计一定“偏心”

关联内容(自动生成)