【Redis】 五大基础数据类型 底层原理深度解析

【Redis】 五大基础数据类型 底层原理深度解析 大家好我是程序员二叉。简介本文深度剖析 Redis 最核心的 5 种基础数据类型String、List、Hash、Set、ZSet。不仅讲解它们的底层数据结构实现还揭秘设计原理、优缺点、以及为什么要这么设计是面试和进阶必备的硬核知识。欢迎点赞关注收藏。一、String 类型底层结构、最大容量、使用场景1. 底层结构SDS (Simple Dynamic String)Redis 没有直接使用 C 语言原生字符串而是自定义了 SDS 动态字符串结构。结构组成len(已用长度) alloc(总容量) flags(类型) buf(字节数组)对比 C 字符串优势O(1) 获取长度无需遍历直接读取 len 属性。杜绝缓冲区溢出修改前先检查容量不足则自动扩容。减少内存重分配空间预分配 惰性空间释放优化修改性能。二进制安全能存图片、视频等二进制数据。2. 最大容量单个 String 类型的Value 最大存储容量为 512MB。注意生产环境尽量避免使用超过 10KB 的大 Key防止网络阻塞。3. 核心使用场景缓存对象JSON 序列化分布式锁计数器INCR命令接口限流分布式 Session二、List 类型底层 QuickList 原理1. 底层结构QuickList快速链表Redis 3.2 之后List 底层完全由 QuickList 实现是经典的「双向链表 压缩列表」结合体。2. QuickList 原理整体结构双向链表每个节点是一个ziplist压缩列表。设计思想双向链表保证头尾操作极快O(1)。压缩列表保证内存紧凑、占用小。节点存储规则一个 quicklistNode 里会放多个元素。元素数量/大小达到阈值就分裂新节点。优点比纯双向链表更省内存。比纯压缩列表修改效率更高。一句话总结QuickList 双向链表保证性能 ziplist 压缩节省内存。三、Hash 类型底层结构、为什么适合存对象1. 底层结构两种编码ziplist压缩列表元素少、值小的时候使用。hashtable字典/哈希表数量多、值大时自动转换。结构类似 Java 的HashMap数组 链表。哈希冲突用链地址法解决。2. 为什么 Hash 最适合存储对象结构天然匹配key - {field:value, field:value}完美对应对象结构。修改效率极高存 String 需要整个对象序列化/反序列化。存 Hash 可以单独修改某个字段如只改用户名不改密码。内存更省元素少时使用 ziplist内存布局连续紧凑。查询更快O(1) 复杂度获取对象的任意属性。3. 最佳实践用户信息、商品详情、配置信息等结构化对象优先用 Hash。四、Set 类型底层、特点、应用场景1. 底层结构intset整数集合元素全是整数且数量少时使用。hashtable字典元素多或非整数时使用。用字典的 key 存元素value 统一为 null。2. 核心特点无序不可重复支持集合运算交集、并集、差集增删查 O(1) 复杂度3. 经典应用场景好友/关注/粉丝关系共同好友、共同关注交集随机抽奖SRANDMEMBER数据去重独立访客 UV 标记五、ZSet 类型跳表 Skiplist 原理、为什么不用红黑树1. 底层结构ZSet 哈希表O(1)查值 跳表O(logn)排序/范围查询哈希表存member-score快速查分值。跳表存score-member做排序、范围查询。2. 跳表 Skiplist 原理跳表是多层有序链表通过建立多级索引实现二分查找效果。每层都是有序链表。最底层包含全部数据。上层是下层的索引查询时从顶层往下跳。时间复杂度 O(logN)效率接近平衡树。简单理解链表 多级索引 跳表。3. 为什么用跳表不用红黑树这是 Redis 最经典面试题核心原因如下范围查询更快更简单ZSet 经常做ZRANGE范围查询。跳表范围查询只需找到起点直接向后遍历。红黑树做范围查询复杂很多。实现更简单、代码更易维护跳表代码只有红黑树的1/3。调试、修改、扩展更安全。高并发下更高效跳表修改只需操作局部节点。红黑树需要频繁旋转平衡开销更大。速度完全够用跳表 O(logN)红黑树 O(logN)。实际性能差距极小跳表优势更大。结论跳表实现简单、范围查询强、效率足够高完全满足 ZSet 需求因此 Redis 选择跳表而不是红黑树。总结String基于 SDS最大 512MB用于缓存、计数、分布式锁。List基于 QuickList双向链表ziplist头尾极快、内存紧凑。Hash基于 ziplist hashtable最适合存对象支持单字段修改。Set基于 intset hashtable去重、集合运算、随机抽取。ZSet基于跳表 哈希表排序性能强跳表比红黑树实现简单、范围查询更强。