1. Redis数据结构概述
Redis作为当今最流行的内存数据库之一,其高性能的核心秘密就在于精心设计的数据结构体系。与传统关系型数据库不同,Redis直接通过数据结构对外提供API,这种"数据结构即接口"的设计理念让操作效率达到极致。我在实际生产环境中使用Redis已有7年,见证了各种数据结构在不同场景下的卓越表现。
Redis的5种基础数据结构(String、List、Hash、Set、ZSet)就像瑞士军刀的不同工具组件,每种结构都有其独特的性能特性和适用场景。理解这些结构的内部实现原理,能帮助我们在开发中做出更合理的技术选型。比如同样是存储用户信息,用String的JSON序列化与用Hash结构就有显著性能差异。
2. 核心数据结构实现原理
2.1 动态字符串SDS
Redis没有直接使用C语言原生字符串,而是自定义了简单动态字符串(Simple Dynamic String)结构。这个设计解决了C字符串的多个痛点:
c复制struct sdshdr {
int len; // 已使用空间
int free; // 剩余空间
char buf[]; // 字节数组
};
-
预分配策略:当SDS需要扩容时,不仅分配必要空间,还会额外预分配一倍容量(最大1MB)。这个策略让连续N次字符串追加操作的时间复杂度从O(N²)降为O(N)。我在处理商品描述文本时,这个特性让批量拼接操作性能提升显著。
-
二进制安全:C字符串以'\0'作为结尾标识,无法存储包含'\0'的数据(如图片)。SDS通过len字段记录长度,可以存储任意二进制数据。这个特性使Redis可以安全地存储序列化后的Protobuf消息。
注意:SDS的预分配策略会导致内存碎片,在存储大量短字符串时应考虑使用jemalloc等内存分配器优化。
2.2 哈希表实现
Redis的字典结构使用两个哈希表实现渐进式rehash,这是保证高性能的关键设计:
- 初始时数据只存储在ht[0]
- 触发扩容时分配ht[1],大小为第一个大于等于ht[0].used*2的2^n
- 后续每次CRUD操作时,将对应bucket从ht[0]迁移到ht[1]
- 迁移完成后释放ht[0],将ht[1
解锁全文
加入我们的会员,获取最新、最热、最精彩的开发者技术内容