Redis 再深入理解一次
前言Redis 是一款高性能内存型 NoSQL 数据库支持多种数据结构、持久化、集群、事务、分布式锁等能力是后端开发缓存、限流、消息队列、分布式会话的标配中间件面试高频考点。本文覆盖基础命令、数据结构、持久化、过期淘汰、缓存设计、高可用、集群、生产问题、性能调优全链路适配 Redis 6.x/ 7.x 主流版本。一、Redis 基础认知1. 核心优势纯内存存储读写毫秒级单节点 QPS 可达十万级丰富数据结构String、List、Hash、Set、ZSet、BitMap、Geo、HyperLogLog、Stream支持持久化 RDB/AOF断电不丢数据主从复制、哨兵、Cluster 集群高可用扩容发布订阅、Lua 脚本、事务、分布式锁原生支持单线程模型无锁竞争命令原子性。2. 适用场景热点数据缓存商品、首页、用户信息分布式锁、接口限流、计数器排行榜ZSet、购物车Hash延时队列、消息队列List/Stream会话存储、验证码、签到统计BitMap地理位置计算Geo、UV 统计HyperLogLog3. 不适合场景大数据持久化存储、复杂多表关联查询、超大文本持久存储。二、五大基础数据结构及实战命令1. String 字符串最常用底层 SDS 动态字符串支持文本、数字、二进制。redisSET key value EX 3600 # 设置过期时间 GET key INCR count # 自增计数器、限流 MSET k1 v1 k2 v2 # 批量操作场景缓存、验证码、分布式计数器。2. Hash 哈希对象存储类似 Map适合存储对象减少序列化开销。redisHSET user:100 id 100 name jack age 20 HGET user:100 name HMGET user:100 id name HDEL user:100 age场景用户信息、购物车、商品基础属性。3. List 双向链表头尾操作 O (1)可做队列、栈。redisLPUSH queue msg1 msg2 # 左入 RPOP queue # 右出 普通队列 LPOP RPUSH 延时队列场景简单消息队列、排行榜、栈。4. Set 无序集合元素唯一redisSADD tag:java user1 user2 SISMEMBER tag:java user1 # 判断是否存在 SINTER 交集、SUNION 并集场景标签、好友关系、去重。5. ZSet 有序集合带分值元素唯一按 score 自动排序分页排行榜神器。redisZADD rank 99 user1 95 user2 ZREVRANGE rank 0 -1 WITHSCORES # 降序排行榜 ZINCRBY rank 5 user1 # 分数累加场景商品销量榜、积分排名、延时任务。三、高级数据结构简述BitMap按位存储签到、布隆过滤器极致省内存HyperLogLog亿级 UV 统计仅占用 12KB允许极小误差Geo经纬度存储附近的人、门店距离计算StreamRedis5.0 消息队列支持消息确认、消费组替代 ListLua 脚本多条命令原子执行分布式锁标准实现。四、Redis 底层核心机制1. 单线程模型IO 多路复用核心命令执行单线程避免线程切换竞争瓶颈不在 CPU而在网络 IO、内存拷贝6.0 引入多线程 IO仅处理网络读写命令执行依旧单线程。2. 过期键删除策略惰性删除访问 key 时才判断过期节省 CPU定期删除后台定时随机抽样删除过期 key 两者结合不会大量过期 key 堆积。3. 内存淘汰策略maxmemory-policy内存满时自动淘汰数据生产常用两种volatile-lru过期 key 中淘汰最少使用缓存首选allkeys-lru所有 key 淘汰最少使用 其余ttl、随机、不淘汰直接报错五、两大持久化方案防止宕机丢失数据1. RDB 快照持久化定时全量二进制快照保存当前全量数据。优点文件小、恢复快、适合备份缺点两次快照间宕机丢失增量数据 触发配置定时 save、手动 bgsave、shutdown。2. AOF 追加日志持久化记录每条写命令重启逐条回放恢复数据。 三种刷盘策略appendfsync always每条命令刷盘零丢失性能极差appendfsync everysec每秒刷盘最多丢 1 秒数据生产推荐appendfsync no交给系统丢失不可控。生产持久化搭配RDB AOF 同时开启RDB 做全量备份AOF 保障增量不丢失。AOF 重写机制AOF 文件持续膨胀后台 fork 子进程重写压缩冗余命令不阻塞主线程。六、事务、Lua 脚本、分布式锁1. Redis 事务 MULTI/EXEC批量命令打包原子执行要么全执行要么全不执行不支持回滚命令语法错误整体失败运行时错误不会回滚WATCH 乐观锁监控 key修改后事务失效。2. Lua 脚本推荐原子操作整个脚本作为一条命令执行原子性更强网络开销更小分布式锁标准实现。lua-- 分布式锁释放脚本 if redis.call(get,KEYS[1]) ARGV[1] then return redis.call(del,KEYS[1]) else return 0 end3. 分布式锁三种方案对比SETNX EXPIRE非原子死锁风险淘汰SET key value NX EX单命令原子加锁基础方案Lua 脚本加解锁安全释放锁生产标准方案锁超时、任务超时解决方案看门狗续期Redisson。七、缓存设计三大经典问题面试核心1. 缓存穿透查询不存在的数据绕过缓存直接打穿数据库。 解决方案缓存空值设置短期过期布隆过滤器拦截非法 key参数校验拦截非法请求。2. 缓存击穿热点 key 过期瞬间大量并发请求打到数据库。 解决方案互斥锁逻辑永不过期后台异步更新过期时间随机偏移避免集体失效。3. 缓存雪崩大量 key 同时过期流量全部压垮 DB。 解决方案过期时间增加随机值集群高可用缓存分片隔离限流熔断、降级兜底。4. 缓存更新策略先更新 DB再删除缓存标准方案延迟双删解决读写不一致 禁止先更新缓存再更新数据库。八、高可用架构演进1. 主从复制 Master-SlaveMaster 写Slave 只读数据异步同步作用读写分离、数据备份缺陷主节点宕机无法自动切换人工运维。2. Sentinel 哨兵主从自动故障转移多哨兵监控集群监控主从状态自动故障检测、客观下线自动选举新 Master通知客户端切换地址 适用中小体量缓存集群。3. Redis Cluster 分片集群生产大规模16384 个哈希槽均匀分配到多主节点水平扩容支持海量数据每主配套从节点故障自动切换客户端分片路由支持跨槽事务受限 扩容缩槽在线迁移无需停机。九、生产最佳实践规范Key 命名规范业务模块:id如order:info:10001统一分隔符长度不宜过长。Value 控制大小单条数据控制 10KB 以内大文件禁止存入 Redis大对象拆分。过期时间统一设计所有缓存 key 必须设置过期避免内存溢出热点 key 随机偏移过期时间。管道 Pipeline 批量操作批量读写使用 Pipeline减少网络往返提升吞吐量。避免高危命令禁止线上使用 KEYS、FLUSHALL、FLUSHDB扫描用 SCAN 游标迭代。内存规划maxmemory 设置物理内存 50%~70%预留系统内存开启内存淘汰。持久化配置线上必开 AOF everysec RDB 定时备份定期异地备份 RDB 文件。连接池优化客户端使用连接池避免频繁创建销毁连接设置合理超时。十、常见线上故障排查CPU 100%大量大 Key 操作、全量 KEYS 命令Lua 脚本复杂计算、慢查询阻塞 排查slowlog 查看慢命令。内存持续暴涨大量 key 未设置过期大对象堆积、内存淘汰策略配置错误 排查redis-cli --bigkeys 统计大 key。主从同步延迟Master 大量写入网络带宽不足从节点磁盘 IO 瓶颈集群槽位迁移失败键未迁移完成、节点网络不通、权限不足。缓存数据不一致更新策略错误、并发读写未加锁、延迟双删缺失。十一、高频面试考点总结Redis 单线程为什么快IO 多路复用机制RDB 和 AOF 区别、各自优缺点、生产如何搭配过期删除 内存淘汰策略有哪些缓存穿透 / 击穿 / 雪崩产生原因与全套解决方案分布式锁实现、死锁如何处理、Redisson 看门狗原理主从复制、哨兵、Cluster 集群三者区别与适用场景Lua 脚本和事务的差异事务是否支持回滚如何排查大 Key、慢查询、CPU 打满问题Redis Cluster 哈希槽扩容原理为什么是 16384String、Hash、ZSet 底层结构与使用场景。十二、结语Redis 学习分为三层基础命令与业务场景 → 缓存一致性三大问题 → 底层持久化、集群高可用。绝大多数线上故障都源于不规范的缓存更新、无过期 key、大 Key、高危命令。 业务开发优先用好缓存分层设计生产环境必须部署哨兵 / Cluster 集群搭配持久化备份、监控告警内存、命中率、慢查询、主从延迟同时做好限流降级兜底保证数据库不被缓存击穿压垮。