)
第91篇Redis核心数据结构2026版《Redis 核心数据结构2026版》2026 年面试Redis 早就不只是“set/get”了本文深度解析 7 种数据结构String、Hash、List、Set、ZSet、HyperLogLog、Bitmap。不仅讲命令更讲底层演进ZipList 为何被 ListPack 取代跳表为什么优于红黑树大 Key 如何量化与治理分布式锁为什么必须用 Redisson附带生产避坑清单 场景决策表 高频面试真题一篇顶十篇。无论你维护老系统还是准备新项目都能找到答案。系列导航《2026全新 | Java 100 天进阶之路从零基础到上岗就业108篇完整学习地图》 |⬅️ 上一篇基础篇完结44篇通关总结 |➡️ 下一篇第93篇Redis面试高频题待发布一、核心知识点Redis 五种核心数据结构 两种高级结构HyperLogLog、Bitmap底层实现的版本演进Redis 6.x vs 7.x常用命令、时间复杂度与 Java 生态对齐生产环境大 Key/热 Key 量化标准与避坑指南场景决策表与面试高频考点二、通俗讲解1分钟开心学1. Redis 是什么Redis 是一个开源的内存数据库读写速度极快微秒级。它就像一个超级快递站数据从硬盘搬到快递站后取货无需再跑仓库。站内分了不同货架普通货架String、标签货架Hash、排队通道List、商品集合Set、积分榜ZSet以及专门的计数器HyperLogLog和签到墙Bitmap。2. 核心数据结构与底层实现⚠️ 2026版关键更新阅读提示Redis 会根据数据量大小自动切换底层编码encoding。下表区分了经典版本与新版实现面试时务必说明版本差异。数据结构Java 类比底层实现Redis ≤6.x / 旧系统底层实现Redis ≥7.x / 新系统典型场景StringStringSDS简单动态字符串SDS不变缓存、计数器、分布式锁HashHashMapZipList HashTableListPack HashTable用户信息、对象存储ListLinkedListQuickList (ZipList LinkedList)QuickList (ListPack LinkedList)消息队列、最新列表SetHashSetIntSet HashTableIntSet HashTable不变去重、抽奖、共同好友ZSetTreeSetZipList SkipList HashTableListPack SkipList HashTable排行榜、延迟队列HyperLogLog-基数估计算法固定12KB不变UV统计、海量去重计数Bitmap-位数组String的位操作不变签到、布隆过滤器、状态标记核心变更说明Redis 7.0 引入ListPack彻底替代 ZipList解决了 ZipList 在插入/删除时可能引发的“连锁更新”性能问题。若你维护的是老系统仍需掌握 ZipList若为新项目或面试ListPack 是必答点。3. 快速选择口诀存简单值 → String存对象 → Hash排队/消息 → List去重/随机 → Set排序/分数 → ZSet海量计数 → HyperLogLog布尔状态 → Bitmap三、实操代码案例 场景说明前置确保本地已安装 Redis通过redis-cli或 Java 客户端Jedis/Lettuce/Redisson连接。1. String 常用命令# 设置值SET user:1张三# 获取值GET user:1# 自增计数器INCR article:123:views# 设置过期时间秒SETEX session:abc3600user_idJavaJedis示例JedisjedisnewJedis(localhost,6379);jedis.set(code,1234);Stringcodejedis.get(code);jedis.expire(code,60);// 60秒过期2. Hash 常用命令# 设置单个字段HSET user:1001 name张三age25# 获取单个字段HGET user:1001 name# 获取全部字段HGETALL user:1001Java 示例MapString,StringusernewHashMap();user.put(name,李四);user.put(age,30);jedis.hset(user:1002,user);Stringnamejedis.hget(user:1002,name);3. List 常用命令# 从右边推入RPUSH messageshelloworld# 从左边弹出队列LPOP messages# 获取范围内的元素LRANGE messages0-14. Set 常用命令# 添加元素SADD tagsJavaRedisSpring# 获取所有元素SMEMBERS tags# 随机弹出一个元素抽奖SPOP tags5. ZSet 常用命令# 添加分数ZADD rank100张三95李四# 按分数降序获取前3名ZREVRANGE rank02WITHSCORES# 增加分数ZINCRBY rank5张三6. HyperLogLog 常用命令# 添加访问用户自动去重PFADD page:uv:20260605user1user2user3# 获取UV估算值误差率约0.81%PFCOUNT page:uv:20260605# 合并多个HyperLogLogPFMERGE page:uv:total page:uv:20260604 page:uv:20260605Java 示例jedis.pfadd(page:uv:20260605,user1,user2);longuvjedis.pfcount(page:uv:20260605);System.out.println(今日UV估算: uv);7. Bitmap 常用命令# 用户签到offset当天是本月第几天SETBIT sign:user:1:20260651# 查询是否签到GETBIT sign:user:1:2026065# 统计本月签到天数BITCOUNT sign:user:1:202606四、生产环境避坑清单2026增强版错误/误区后果正确做法用 String 存对象 JSON修改需整体读写性能差用 Hash 存储对象字段生产环境用KEYS *阻塞 Redis性能灾难用SCAN游标渐进式遍历List 当队列频繁LPOP空检查无数据时 CPU 空转用BLPOP/BRPOP阻塞读ZSet 成员分数相同按字典序排列与预期不符分数设计为score.timestamp组合大 Key 操作如 HGETALL 千万字段慢查询阻塞主线程用HSCAN分批量化标准见下方Hash/ZSet 当日志无节制写入数据量过大转为 hashtable引发大 Key设置合理 TTL或使用专业时序库手写 SETNX 实现分布式锁死锁、误删、过期业务未完成生产环境直接用 Redisson内置 WatchDog 自动续期大 Key 量化标准阿里云/业界通用String 类型 value 10KB集合/列表/哈希 元素数量 1000个排查工具redis-cli --bigkeys、MEMORY USAGE key、SCAN 脚本定期巡检热 Key 发现redis-cli --hotkeys需开启 LFU 淘汰策略或 客户端埋点统计五、场景选择决策表场景需求推荐数据结构原因示例命令存储对象属性如用户信息Hash可单独操作字段无需整体序列化HSET user:1 name Bob age 25文章计数器StringINCR命令天然支持原子性自增INCR article:123:views最新评论列表List支持在表头/表尾插入新元素保证顺序LPUSH comments:article:1 good抽奖系统随机抽取中奖者SetSRANDMEMBER或SPOP支持随机获取去重元素SRANDMEMBER lottery 3商品排行榜ZSet通过score排序能快速获取 Top NZREVRANGE rank 0 4 WITHSCORES用户唯一标签Set元素自动去重支持交并差集SADD tags:article:1 Java Redis数值去重计数大流量UVHyperLogLog占用内存固定12KB误差1%PFADD uv user1大量布尔值状态签到/布隆Bitmap位级存储空间效率极高SETBIT sign:u:1 5 1地理位置搜索附近的人、门店Geo基于 ZSet 实现经纬度存储与半径查询GEOADD locations 116.397 39.908 鸟巢GEORADIUS locations 116.397 39.908 10 km消息队列 / 事件流Stream支持消费者组、消息持久化、ACK 确认XADD mystream * user 123XREADGROUP GROUP g1 c1 STREAMS mystream 选型速查前6行为基础场景后4行为高级/专用场景HyperLogLog、Bitmap、Geo、Stream。面试时优先掌握前6行系统设计题重点使用后4行展现深度。六、面试高频考点Q1Redis 为什么这么快① 纯内存操作② 单线程模型避免上下文切换和锁竞争③ 高效的数据结构如 SDS、跳表等④ 非阻塞 I/O多路复用。Q2Redis 的 String 底层实现是什么SDSSimple Dynamic String预分配空间减少扩容开销记录长度实现 O(1) 取长度二进制安全。Q3ZSet 底层为什么用跳表而不是红黑树跳表实现简单性能接近红黑树O(logN)且支持范围查询ZRANGE比红黑树更高效。Q4使用 SETNX 实现分布式锁有什么潜在问题生产环境怎么做① 死锁风险需设置过期时间② 锁误删需唯一标识Lua原子删除③ 锁过期业务未完成需看门狗续期。生产标准答案不要手写直接使用Redisson框架。它封装了可重入锁、WatchDog 自动续期默认30s每10s检查一次、RedLock 多节点方案是经过大规模验证的工业级实现。Q5Redis 与 Memcached 的区别Redis 数据结构丰富支持持久化、集群、事务Memcached 仅支持 String多线程但无持久化。Q6KEYS *和SCAN的区别KEYS *会阻塞 Redis 线程生产环境禁用SCAN是渐进式的每次返回少量数据不影响服务。Q7如何实现一个抽奖系统使用Set的SPOP随机弹出或SRANDMEMBER随机取不弹出。例如SADD lottery user1 user2 user3SPOP lottery 1随机抽取一名。Q8Redis 能存储多少 key理论上最大 2^32实际受内存限制。单个 key 最大 512MBString 类型。Q9Redis 7.x 为什么用 ListPack 替代 ZipListZipList 在插入/删除中间元素时可能触发“连锁更新”cascade update最坏情况时间复杂度退化为 O(N²)。ListPack 采用独立长度编码每个元素自包含长度信息彻底消除连锁更新同时保持紧凑内存布局。这是 Redis 7.0 最重要的底层优化之一。Q10如何排查和治理大 Key① 发现redis-cli --bigkeys离线扫描、MEMORY USAGE在线检测、RDB 分析工具如 rdb-tool② 治理拆分大 Key如 Hash 拆分为多个小 Hash、异步删除UNLINK代替DEL、设置 TTL 自动过期、业务层限流避免突发写入。七、练习题设计用 ZSet 实现文章阅读排行榜要求可随时增加阅读数并获取 top 10。思路ZINCRBY rank:article 1 articleId原子自增ZREVRANGE rank:article 0 9 WITHSCORES获取前10。注意分数相同时加时间戳保证稳定性。代码用 Redisson 实现一个可重入分布式锁设置30秒过期。思路RLock lock redisson.getLock(“order” orderId);lock.lock(30, TimeUnit.SECONDS);try { … } finally { lock.unlock(); }重点理解 WatchDog 仅在未指定 leaseTime 时生效。思考为什么 ZSet 的ZRANGE时间复杂度是 O(logN M)而ZRANGEBYSCORE也是类似的思路跳表定位起点 O(logN)顺序遍历 M 个节点 O(M)。两者区别在于ZRANGEBYSCORE可能需要跳过不符合分数范围的节点但平均仍是 O(logN M)。面试官考察的是对跳表范围查询原理的理解。 你的学习进度当前第91篇 / 共108篇 ·进阶篇缓存与消息队列第91~96篇✅ 已完成基础篇44篇 第91篇 正在学第91篇⏳ 待学习第92~108篇 完整目录 学习指南 | 订阅本专栏不错过每一篇 本专栏每篇都包含避坑表 面试高频考点 练习题。每天30分钟100天拿offer 下一篇文章预告《第93篇Redis面试高频题》内容简介缓存穿透/击穿/雪崩的区别与解决方案、Redis 持久化RDB/AOF选型、淘汰策略、分布式锁实现、Big key 治理。 学完这篇你将能应对 90% 的 Redis 面试题告别“只会 set/get”。福利提醒本文提到的ListPack、跳表、SDS底层原理在进阶篇后续会有专题源码级剖析。提前订阅本专栏或关注作者确保不错过每一篇深度干货《Java 100 天进阶之路 | 从入门到上岗就业》每天一篇建议收藏 关注一起100天拿offer 点击关注我更新后第一时间收到推送 除了《Java 100 天进阶之路 | 从入门到上岗就业》系列文章我也在深挖智能物流实战出版社WMS、托盘调度、机器学习落地。如果你对技术在不同领域的实战感兴趣欢迎点击我的头像看看专栏《出版社物流WMS智能调度实战》。技术相通思路可鉴。