# Redis 全攻略:从入门到架构实战

发布时间:2026/5/25 21:49:07

# Redis 全攻略:从入门到架构实战 目录Redis 简介与概述Redis 安装与基本操作核心数据结构详解3.1 String (字符串)3.2 List (列表)3.3 Set (集合)3.4 Hash (哈希)3.5 Sorted Set (有序集合)3.6 高级数据结构 (Bitmaps, HyperLogLog, GEO, Stream)Redis 高级特性4.1 发布订阅 (Pub/Sub)4.2 事务与 Lua 脚本4.3 Pipeline 管道技术持久化机制5.1 RDB (快照)5.2 AOF (追加文件)5.3 混合持久化高可用与分布式架构6.1 主从复制 (Replication)6.2 哨兵模式 (Sentinel)6.3 Redis Cluster 集群性能优化与内存管理7.1 内存淘汰策略7.2 键值设计优化7.3 慢日志查询实战场景应用8.1 分布式锁 (Redlock)8.2 缓存设计与穿透/雪崩/击穿8.3 排行榜与计数器8.4 消息队列 StreamRedis 运维与监控9.1 常用命令与 info 详解9.2 安全与权限控制9.3 可视化工具高频面试题与进阶思考1. Redis 简介与概述Redis(Remote Dictionary Server) 是一个开源的、基于内存的数据结构存储系统它可以用作数据库、缓存和消息中间件。核心特点内存数据库数据主要存储在内存中读写速度极快微秒级。数据结构丰富原生支持字符串、哈希、列表、集合、有序集合等而非简单的 Key-Value。持久化支持 RDB 和 AOF 两种方式将内存数据保存到磁盘保证数据安全性。高可用与分布式原生支持主从复制、哨兵和集群模式。单线程模型Redis 的核心处理是单线程的指网络请求模块避免了多线程的竞争开销同时利用 I/O 多路复用epoll实现高并发。为什么 Redis 如此之快纯内存操作数据在内存中存取速度是磁盘的千百倍。单线程模型没有线程上下文切换和锁竞争的开销。I/O 多路复用利用 epoll 模型单线程处理大量客户端连接。高效的数据结构底层使用 SDS、跳表、压缩列表等高效结构。2. Redis 安装与基本操作2.1 Linux 安装# 下载wgethttps://download.redis.io/releases/redis-7.0.0.tar.gztar-xzfredis-7.0.0.tar.gzcdredis-7.0.0# 编译makemakeinstallPREFIX/usr/local/redis# 启动src/redis-server redis.conf2.2 Docker 安装bash复制下载docker run -d --name redis -p 6379:6379 redis:7.02.3 基本配置 (redis.conf)conf复制下载# 绑定 IP bind 0.0.0.0 # 端口 port 6379 # 后台运行 daemonize yes # 密码 requirepass yourpassword # 日志级别 loglevel notice2.4 连接测试bash复制下载redis-cli -h 127.0.0.1 -p 6379 -a password ping PONG3. 核心数据结构详解3.1 String (字符串)内部编码int(整数),embstr(短字符串),raw(长字符串)。使用场景缓存对象、计数器、分布式锁、Session 共享。常用命令redis复制下载SET key value [EX seconds] [NX|XX] GET key INCR key # 原子自增 MSET k1 v1 k2 v2 # 批量底层结构Redis 自己实现了 SDS (Simple Dynamic String)支持 O(1) 获取长度预分配空间减少内存碎片二进制安全。3.2 List (列表)底层实现Redis 3.2 之前使用ziplistlinkedlist3.2 之后统一使用quicklist双向链表 压缩列表的组合。特点有序、可重复、支持双向操作。使用场景消息队列LPUSH BRPOP、最新动态列表LTRIM 限制长度。常用命令redis复制下载LPUSH key value # 左侧插入 RPUSH key value # 右侧插入 LPOP key BRPOP key timeout # 阻塞弹出 LRANGE key 0 -1 # 获取全部3.3 Set (集合)底层实现intset(整数集合) 或hashtable。特点无序、唯一。使用场景标签系统、社交关系共同关注、抽奖SRANDMEMBER。常用命令redis复制下载SADD key member SREM key member SMEMBERS key SINTER key1 key2 # 交集 SUNION key1 key2 # 并集 SCARD key # 元素个数3.4 Hash (哈希)底层实现ziplist(压缩列表) 或hashtable(字典)。当字段少且值小时用 ziplist以节省内存。使用场景存储对象如用户信息、商品详情相比 String 序列化存储Hash 可以单独修改某个字段减少网络开销。常用命令redis复制下载HSET user:1 name John age 30 HGET user:1 name HGETALL user:1 HINCRBY user:1 age 1 # 字段自增3.5 Sorted Set (有序集合)底层实现ziplist或skiplist(跳表) hashtable。当元素数量多或元素值大时使用跳表。特点唯一性 分数排序。使用场景排行榜、延迟队列时间戳作为 score、带权重的消息队列。常用命令redis复制下载ZADD key score member ZRANGE key 0 -1 WITHSCORES # 升序 ZREVRANGE key 0 -1 WITHSCORES # 降序 ZINCRBY key increment member ZRANGEBYSCORE key min max跳表原理跳表是一种多层链表结构通过维护多级索引实现 O(log N) 的查询复杂度类似于二分查找在链表上的实现。3.6 高级数据结构3.6.1 Bitmaps (位图)本质上是一个字符串按位操作。用于记录用户签到、在线状态等海量布尔值场景。redis复制下载SETBIT user:sign:100 0 1 # 用户100第1天签到 GETBIT user:sign:100 0 BITCOUNT user:sign:100 # 统计签到次数3.6.2 HyperLogLog基于概率算法的基数统计用于统计 UV (独立访客)误差在 0.81% 左右占用内存极小每个键 12KB。redis复制下载PFADD uv:20241001 user1 user2 PFCOUNT uv:202410013.6.3 GEO (地理位置)基于 Sorted Set 实现存储经纬度支持计算距离、范围查找。redis复制下载GEOADD city 116.40 39.90 Beijing GEODIST city Beijing Shanghai km GEORADIUS city 116.40 39.90 100 km3.6.4 Stream (消息队列)Redis 5.0 引入类似于 Kafka 的持久化消息队列支持消费者组、消息确认、回溯消费。redis复制下载XADD mystream * name Redis XREAD COUNT 1 STREAMS mystream 0 XGROUP CREATE mystream mygroup 0 XREADGROUP GROUP mygroup consumer1 STREAMS mystream 4. Redis 高级特性4.1 发布订阅 (Pub/Sub)模式生产者发布消息到频道消费者订阅频道。消息即发即失不持久化。命令redis复制下载SUBSCRIBE channel PUBLISH channel message PSUBSCRIBE news.* # 模式订阅缺点不保证消息可靠送达客户端断线重连后无法收到断线期间的消息。适合实时性高、允许丢失的场景如实时聊天室。4.2 事务与 Lua 脚本Redis 事务通过MULTI、EXEC、DISCARD、WATCH实现。redis复制下载MULTI SET key1 value1 SET key2 value2 EXEC特性事务中的命令会按顺序执行不具备原子回滚如果某条命令执行失败其他命令依然会执行。Lua 脚本通过EVAL执行 Lua 脚本Redis 保证脚本执行期间原子性且脚本会被缓存SCRIPT LOAD/EVALSHA极大减少网络开销。lua复制下载-- 原子性扣减库存 EVAL local stock redis.call(get, KEYS[1]) if stock tonumber(ARGV[1]) then redis.call(decrby, KEYS[1], ARGV[1]) return 1 else return 0 end 1 stock_key 14.3 Pipeline 管道技术问题传统请求-响应模型每次命令都需等待 RTT (往返时间)。解决Pipeline 允许客户端一次性发送多条命令服务端依次执行后一次性返回减少网络开销。注意Pipeline 不是原子操作且数据量过大可能导致内存阻塞。java复制下载// Java Jedis 示例 Pipeline p jedis.pipelined(); for (int i 0; i 1000; i) { p.set(key i, value i); } p.sync();5. 持久化机制5.1 RDB (快照)原理在指定时间间隔内将内存中的数据集快照写入磁盘dump.rdb。触发方式手动SAVE(阻塞) 或BGSAVE(fork 子进程后台执行)。优点文件紧凑恢复速度快适合灾难恢复。缺点如果服务器宕机会丢失最后一次快照后的数据fork 子进程时如果数据量大可能导致短暂卡顿。配置conf复制下载save 900 1 # 900秒内至少有1次修改 save 300 10 stop-writes-on-bgsave-error yes5.2 AOF (追加文件)原理记录服务器执行的所有写操作命令类似 MySQL 的 binlog重启时重放命令。同步策略appendfsync always每命令同步最安全性能差。appendfsync everysec每秒同步一次默认最多丢失1秒数据。appendfsync no由操作系统决定。优点数据安全性高最多丢失1秒数据。缺点文件体积大恢复速度慢。重写机制为了解决 AOF 文件膨胀Redis 会 fork 子进程执行BGREWRITEAOF将内存数据转换为命令写入新 AOF 文件。conf复制下载appendonly yes appendfilename appendonly.aof appendfsync everysec auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb5.3 混合持久化 (Redis 4.0)在 AOF 重写时将 RDB 文件内容写入 AOF 文件头部后续增量命令追加在后面。结合了 RDB 恢复快和 AOF 数据安全的优点。conf复制下载aof-use-rdb-preamble yes6. 高可用与分布式架构6.1 主从复制 (Replication)原理Slave 向 Master 发送SYNC或PSYNC命令。Master 启动后台线程保存 RDB 快照将快照发送给 Slave并缓存期间的新命令最后 Slave 加载 RDB 并执行缓存命令完成同步。特点读写分离Master 写Slave 读缓解读压力。配置replicaof masterip masterport复制模式全量复制Slave 首次连接或断连太久时发生开销较大。部分复制基于复制积压缓冲区repl_backlog断连重连后Master 将缺失的命令发送给 Slave。6.2 哨兵模式 (Sentinel)用于解决主从复制下的自动故障转移问题。Sentinel 是一个独立的进程监控 Master 和 Slaves 的健康状态。功能监控检查节点是否正常运行。通知当节点异常时通知管理员或应用程序。自动故障转移如果 Master 下线Sentinel 会选举一个 Slave 升级为新的 Master并修改其他 Slave 的配置。配置中心客户端连接 Sentinel 获取当前 Master 地址。主观下线单个 Sentinel 认为 Master 不可达。客观下线多个 Sentinel达到 quorum 数量都认为 Master 不可达触发故障转移。典型配置(sentinel.conf)conf复制下载sentinel monitor mymaster 127.0.0.1 6379 2 sentinel down-after-milliseconds mymaster 30000 sentinel parallel-syncs mymaster 1 sentinel failover-timeout mymaster 1800006.3 Redis Cluster 集群当数据量过大单节点内存不足或单节点写压力过大时需要使用集群。架构无中心架构通过分片Sharding将数据分散到多个 Master 节点每个 Master 可有多个 Slave。分片算法哈希槽 (Hash Slot)总共 16384 个槽位。CRC16(key) % 16384决定 key 落在哪个节点。特点支持节点动态扩缩容数据自动迁移。部分节点故障不影响整体服务只要槽位对应的主从不全部挂掉。客户端直连节点无需代理。限制不支持跨节点事务不支持多数据库批量操作如 mget要求所有 key 在同一个槽位可通过 hash tag 解决如{user:100}:name。搭建命令bash复制下载redis-cli --cluster create 127.0.0.1:7000 127.0.0.1:7001 ... --cluster-replicas 1重定向当客户端请求的 key 不在当前节点时节点返回MOVED或ASK重定向指令引导客户端去正确节点。7. 性能优化与内存管理7.1 内存淘汰策略当 Redis 内存达到maxmemory限制时需要执行淘汰策略。noeviction不淘汰直接返回写错误默认。allkeys-lru在所有 key 中淘汰最近最少使用的。volatile-lru在设置了过期时间的 key 中淘汰 LRU。allkeys-random随机淘汰。volatile-random在过期 key 中随机淘汰。volatile-ttl淘汰剩余生存时间最短的 key。allkeys-lfu(4.0)淘汰最不经常使用的。volatile-lfu(4.0)在过期 key 中淘汰 LFU。LRU vs LFULRU最近最少使用基于访问时间。LFU最不经常使用基于访问频率和衰减因子能避免缓存污染一次性访问大量冷数据将热数据挤出去。7.2 键值设计优化压缩键名避免使用过长的 key如com:company:user:info:${id}可以缩写为c:c:u:${id}。使用 Hash 而非 String 序列化对于对象使用 Hash 存储单个字段避免每次修改都要整体序列化/反序列化节省内存和网络。数据压缩对于大的 value如 JSON可以在客户端使用 snappy/gzip 压缩后再存入 Redis。设置过期时间所有缓存数据尽量设置 TTL防止内存溢出。7.3 慢日志查询记录执行时间超过指定阈值的命令用于定位性能瓶颈。bash复制下载CONFIG SET slowlog-log-slower-than 10000 # 微秒 CONFIG SET slowlog-max-len 128 SLOWLOG GET 108. 实战场景应用8.1 分布式锁在分布式系统中需要锁来保证资源互斥访问。基本方案SET key value NX EX seconds(原子性设置锁只有不存在时设置并设置过期时间)。释放锁使用 Lua 脚本检查 value 是否匹配防止误删别人的锁后再删除。lua复制下载-- 释放锁 Lua 脚本 if redis.call(get, KEYS[1]) ARGV[1] then return redis.call(del, KEYS[1]) else return 0 endRedlockRedis 作者提出的算法用于在多个 Redis 实例上获取锁以解决单点故障和时钟漂移问题。但在实际复杂环境中推荐使用红锁或直接使用 ZooKeeper/etcd。8.2 缓存设计与穿透/雪崩/击穿8.2.1 缓存穿透现象查询不存在的数据请求直接打到数据库。解决布隆过滤器将所有可能存在的数据哈希到一个足够大的 bitmap 中过滤掉不存在的数据请求。缓存空对象对于查询为空的 key也缓存一个空值设置短过期时间。8.2.2 缓存击穿现象热点 key 过期瞬间大量并发请求直接打到数据库。解决互斥锁只允许一个线程去查询数据库其他线程等待。逻辑过期不设置物理过期使用后台线程异步刷新缓存。8.2.3 缓存雪崩现象大量 key 同时过期或 Redis 宕机导致流量涌入数据库。解决过期时间随机给缓存过期时间加上随机值。高可用部署搭建 Redis 集群或哨兵避免单点故障。服务熔断降级如果 Redis 不可用返回默认值或错误保护数据库。8.3 排行榜与计数器实时排行榜使用 Sorted Setscore 为分数ZREVRANGE获取 Top N。多维排序如果排序需要多维度如先按分数再按时间可以将分数和时间的组合作为 score例如score 分数 * 1000000 (MAX_TIME - 时间戳)。计数器INCR命令天然支持原子自增可用于文章阅读数、点赞数、限流滑动窗口等。8.4 消息队列 StreamRedis Stream 相比 List 实现了更完善的消息队列功能。消费者组多个消费者可以共同消费同一队列且每个消息只会被组内的一个消费者消费。消息确认XACK确保消息被可靠处理未确认的消息可被XPENDING查询并XCLAIM重新认领。消费回溯支持从任意 ID 开始消费。典型模式redis复制下载# 生产者 XADD mystream * task do something # 消费者组创建 XGROUP CREATE mystream mygroup 0 MKSTREAM # 消费者读取 XREADGROUP GROUP mygroup consumer1 BLOCK 2000 STREAMS mystream 9. Redis 运维与监控9.1 常用命令与 info 详解INFO查看服务器信息包括server,clients,memory,stats,replication,keyspace等。MONITOR实时监控服务器接收到的命令生产环境慎用性能开销大。CLIENT LIST查看连接的客户端。DBSIZE查看当前库 key 数量。MEMORY USAGE key查看某个 key 的内存占用。关键指标used_memory_rss操作系统视角的物理内存。mem_fragmentation_ratio内存碎片率过高可能需重启。instantaneous_ops_per_sec当前 QPS。rejected_connections因 maxclients 限制拒绝的连接数。9.2 安全与权限控制密码requirepass设置密码或使用 ACL (Access Control List) 实现精细权限控制Redis 6.0。ACL 示例bash复制下载ACL SETUSER alice on password ~* all ACL SETUSER bob on pass ~cached:* get set禁用危险命令在生产环境可通过rename-command重命名或禁用FLUSHALL,FLUSHDB,CONFIG等命令。9.3 可视化工具RedisInsight官方 GUI功能强大。Another Redis Desktop Manager跨平台简洁高效。命令行redis-cli --stat实时查看统计。10. 高频面试题与进阶思考1. Redis 为什么是单线程的6.0 为什么引入多线程核心处理模型是单线程避免锁开销且内存操作 I/O 多路复用足以支撑高并发。6.0 引入多线程主要用于网络 I/O 读写的异步处理提高大包传输时的性能但执行命令依然是单线程。2. Redis 的过期删除策略惰性删除访问 key 时检查是否过期。定期删除每秒执行 10 次随机抽取一批设置了过期时间的 key删除其中过期的。由于惰性删除可能造成内存泄漏定期删除弥补了这一点。3. 如何保证 Redis 与数据库的双写一致性先更新数据库再删除缓存Cache Aside Pattern。如果先删缓存可能会由于数据库更新延迟导致脏数据。如果要求强一致性可使用订阅数据库 binlog如 Canal异步更新缓存或使用读写锁。4. Redis 的管道Pipeline与事务Transaction的区别Pipeline 是为了减少 RTT不保证原子性多条命令之间可能插入其他客户端的命令。Transaction 保证了命令顺序执行的隔离性串行化但不支持回滚。5. 什么是 BigKey如何发现和处理BigKey 指 value 过大如 String 大于 10KB集合元素过多。危害阻塞网络、阻塞 Redis如hgetall、导致数据迁移困难。发现redis-cli --bigkeys或分析 rdb 文件。处理拆分为多个小 key使用 Hash 分片或者将冷数据迁移到其他存储。6. 什么是 HotKey如何解决热 Key 指被高频访问的 Key如秒杀商品。解决本地缓存Caffeine Redis 多级缓存读写分离多 Slave 分担读或者将热 Key 分散如加随机后缀。7. Redis 有哪些禁用命令KEYS *会阻塞 Redis应使用SCAN代替。FLUSHALL/FLUSHDB破坏性操作。CONFIG SET动态修改配置可能引起风险。总结Redis 凭借其丰富的数据结构、极致的性能和高可用的架构已成为现代后端开发中不可或缺的组件。本文从零开始涵盖了从单机安装到集群部署、从核心 API 到底层原理、从缓存设计到生产运维的方方面面。掌握 Redis 不仅仅是会使用几条命令更重要的是理解其内存管理、持久化权衡、分布式一致性以及在复杂业务场景下的最佳实践。希望这份全攻略能帮助您在面试、开发和架构设计中游刃有余。

相关新闻