整体理解Redis底层数据结构
核心领域
针对Redis底层数据结构进行深度解析,涵盖String、Hash、List、Set、ZSet,对比了Redis6(ziplist)与Redis7(listpack)的差异。
不同数据类型分析
| 数据类型 | 关键结构 | 编码类型 | 版本差异 | 转换条件 |
|---|---|---|---|---|
| String | SDS | int/embstr/raw | 无差异 | 值为可转换为long类型数字时用int;为字符串且长度小于44字节用embstr;长度大于44字节用raw |
| Hash | dict/listpack | listpack/hashtable | Redis7用listpack替代ziplist | 键值对不超512个且键值对字符串长度不超64字节用listpack,否则用hashtable |
| List | quicklist/listpack | listpack/quicklist | Redis7改用listpack | 数据量较小时用listpack,由list - max - listpack - size参数决定;数据量大时用quicklist |
| Set | intset/listpack | intset/listpack/hashtable | 无差异 | 数据为不超64位数字用intset;非数字且未超set - max - listpack - entries(128)和set - max - listpack - value(64)阈值用listpack;超阈值用hashtable |
| ZSet | skiplist/listpack | listpack/skiplist | Redis7改用listpack | value数据量小,由zset - max - listpack - entries和zset - max - listpack - value衡量时用listpack;数据量大时用skiplist |
其他要点
- RedisObject统一封装机制1. :作为<k, v>型数据库,key通常是string类型字符串对象,value是redisObject对象,结构包含type、encoding、lru、refcount和*ptr字段。
- 五大数据类型底层编码策略:根据数据类型、长度、数量等因素综合选择合适编码。
- Redis7中listpack对ziplist的替代方案:listpack解决了ziplist连锁更新问题,entry记录自身长度而非前向长度。
- 内存优化技术:embstr使用连续内存,listpack无连锁更新。
- 面试高频考点:SDS结构解决C语言字节数组保存字符串问题;quicklist结合数组和链表优点;跳表用空间换时间,适合读多写少场景。
创新性
- listpack革命性改进:通过记录自身长度替代前向长度,解决ziplist连锁更新问题。
- SDS多结构适配:针对不同字符串长度采用int/embstr/raw分级策略。
- quicklist混合结构:数组(listpack)与链表结合。
普适性原则
- 内存紧凑原则:所有结构追求连续内存分配,如embstr、listpack。
- 分级存储策略:小数据用紧凑结构,大数据用链表,在List、Hash中通用。
- 读写优化平衡:skiplist以空间换时间,适合读多写少场景。
实用性指南
- 配置优化:
hash - max - listpack - value 64控制Hash编码转换,zset - max - listpack - entries 128影响ZSet结构选择。 - 性能调优:小整数(<1000)复用共享对象,embstr避免小字符串内存碎片。
- 面试重点:listpack与ziplist结构差异、RedisObject结构体字段含义、quicklistNode的entry指向机制。
全面性覆盖
涵盖Redis核心数据结构,如String的3种编码、Hash的2种编码、List的2种编码、Set的3种编码、ZSet的2种编码。
客观性验证
- 源码片段验证,如server.h 880行编码定义。
- 实时调试指令,如OBJECT ENCODING验证。
- 配置参数实测,修改参数观察编码变化。