ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Redis核心技术与实战:从数据类型、持久化到缓存治理与故障排查

Redis核心技术与实战:从数据类型、持久化到缓存治理与故障排查 简介面向 Redis 核心原理与实际运维场景的系统知识包适合有一定使用经验、希望深入理解内部机制并提升性能优化与高可用设计能力的开发者。内容按基础篇与实践篇两大模块编排基础篇覆盖键值数据库基本架构、Redis 数据结构、单线程高性能 IO 模型、AOF 日志与内存快照、主从同步、哨兵机制、切片集群等核心主题实践篇聚焦 String 类型优化、海量 key 统计、GEO 与自定义数据类型、时间序列数据保存、消息队列方案、单线程阻塞规避、CPU 结构影响、响应延迟波动排查等高频问题并附有第 19 讲课后思考题答案与常见问题答疑便于读者自查对照。压缩包体量约 856MB上游未提供文件数量与类型明细目录按课程章节组织可从基础逐步过渡到实战。目前已有 47 人学习适合需要系统梳理 Redis 知识体系、应对生产环境性能排查与架构选型的进阶读者。1. 拿到的不是安装包是 Redis 从入门到抢救的全套思路很多人看到Redis核心技术与实战.zip这个标题第一反应是又一个资源包、一套视频课或者一份速查手册。但真正做过几年后端的人会意识到Redis 从来不是装个 redis-server、敲两条命令就能收工的东西。它是缓存是分布式锁是消息队列也是生产环境里最常背锅的中间件——缓存穿透打垮数据库、主从切换丢数据、内存碎片涨到不可控、序列化方式选错导致乱码这些才是 Redis 实战里的高频事故点。这个 zip 背后真正值得拆解的是 Redis 的核心机制加上一套能落地的排障思路。这篇笔记不讨论怎么找个链接下载解压而是顺着 Redis 核心技术这条线把单机部署、主从复制、持久化策略、分布式锁、缓存治理和故障排查这些真实场景讲透。新手能照着命令一步步跑起来熟手也能看到参数设置的边界和踩坑记录。热词里那些Redis缓存穿透Redis分布式锁docker安装redis主从redis command timed out之类的痛点后面都会逐一对应到具体章节里。先从一句话明确 Redis 在系统里的位置它是内存型键值存储速度极快但数据安全、一致性和运维复杂度决定了它好用但不好养。所以这篇实战笔记的核心思路是——先理解 Redis 的底层设计再动手搭环境最后用真实事故复盘来补上那些文档里不会写的坑。2. Redis 核心机制从数据结构到持久化搞懂这些才敢上生产2.1 五种基本数据类型和它们的适用边界别只会 StringRedis 最基础的五种数据类型是 String、Hash、List、Set、ZSet。热词里单独的redis数据类型搜索量很高说明很多人卡在了知道有这些类型但不知道生产里怎么选这一步。我见过的典型误用是不管什么场景都用 String 一把梭结果订单的多个字段存了五六个 key更新一个字段要读出来反序列化再写回去性能和代码复杂度都很差。String 适合存简单的键值、计数器、Token、验证码底层是 SDS追加和修改操作性能好但别拿它存结构化的对象数据。Hash 才是存对象字段的正解比如用户信息、商品详情一个 key 对应多个 field修改单个字段不影响其他字段而且 Hash 内存碎片比大量 String 少因为同一个小对象在 Redis 里会被压缩编码成 ziplist 或 listpack 存储。List 在消息队列场景里被过度吹捧了它做简单的任务队列可以但一旦需要 ACK 机制、消息确认、重复消费控制你会发现自己在一个个手搓消息队列的轮子。实际项目中用 List 做时间线、做简单阻塞队列是合理的比如 LPUSH BRPOP 配合实现一个可靠的工作队列。Set 做标签系统、抽奖去重这类需要交并补操作的场景很顺手。ZSet 则是排名榜、延迟队列、滑动窗口限流的底层支撑因为它的分值排序是天然的特性。生产上有个常被忽略的点Redis 3.2 之后引入了 List 的 quicklist 结构ZSet 在元素少时用 ziplist这些内部编码的细节决定了内存和行为。用 OBJECT ENCODING 命令可以查看某个 key 的实际编码排查内存问题时这个命令很有用。2.2 持久化 RDB 和 AOF到底怎么组合才不丢数据Redis 持久化是Redis持久化Redis持久化机制详解这些热词背后的核心需求。先说结论只在缓存场景允许关持久化任何有业务价值的 Redis 数据都必须开启持久化而且大多时候要 RDB AOF 同时开。RDB 是快照式持久化把某一时刻的数据全量刷到磁盘。触发方式有 save阻塞、bgsavefork 子进程和配置里的 save 规则。bgsave 时 Redis 会 fork 出一个子进程做快照主进程继续服务但 fork 瞬间如果内存过大或者机器性能差会出现明显的卡顿。RDB 的优点是恢复快、文件紧凑缺点是两次快照之间的数据会丢而且 fork 开销大。AOF 是追加式日志记录每一条写命令。它有三种 fsync 策略always每条命令都刷盘最安全但最慢、everysec每秒刷一次性能和数据安全折中、no交给操作系统决定最快但丢数据风险最大。生产上 everysec 是常见选项。AOF 最大的坑是文件膨胀需要通过 BGREWRITEAOF 重写瘦身。实际项目中我一般这样配# 开启 AOF appendonly yes appendfilename appendonly.aof # 每秒刷盘性能和数据安全折中 appendfsync everysec # 开启 RDB 快照作为兜底 save 900 1 save 300 10 save 60 10000 # 优雅关闭时自动触发 RDB stop-writes-on-bgsave-error yes rdbcompression yes rdbchecksum yessave 命令的意思是900 秒内至少有 1 次写操作就做一次快照300 秒内有 10 次写操作就做60 秒内有 10000 次写操作就做。这三条是 Redis 默认的配置实践中可以保留但如果 Redis 只承担纯缓存角色且数据可以容忍一定时间窗口丢失就只留 AOF。stop-writes-on-bgsave-error yes 意味着 RDB 写盘失败时 Redis 会停止接收写入这是用可用性换数据安全的保守策略生产里要根据业务容忍度决定是否改为 no。2.3 内存淘汰策略Redis 满了不一定会崩溃但一定会有你想不到的后果热词里Redis缓存治理Redis缓存穿透说明很多人是被缓存问题逼到学习 Redis 的。Redis 内存满了之后如果没有配置 maxmemory-policy写入操作会直接报 OOM 错误但这不是最可怕的。最怕的是你配了 noeviction默认策略不淘汰任何 key写满即报错然后线上突然涌入大量冷数据Redis 直接拒绝写入业务链路全部告警。生产上常见的淘汰策略有这几种allkeys-lru对所有 key 做 LRU 近似淘汰最常用、volatile-lru只对有 TTL 的 key 做 LRU 淘汰适合冷热数据分明且热数据不设 TTL 的场景、allkeys-random随机淘汰适合缓存数据访问概率均等的场景、volatile-ttl淘汰剩余 TTL 最短的 key适合对时效敏感的数据。还有 Redis 4.0 加入的 LFU 策略allkeys-lfu 适合热点数据相对固定且需要长期保留的场景因为它统计的是访问频率而不是最近访问时间能避免一次批量访问把一个冷 key 顶替掉。一个常见的记忆误区是LRU 和 LFU 都是近似实现不是精确的Redis 是在内存池里抽一批样本做淘汰默认样本数 maxmemory-samples 是 5调大到 10 会让淘汰更精确但 CPU 开销增加。我见过有人把 maxmemory-samples 调到 100 追求精确淘汰结果 Redis 实例性能掉了 20%这是典型的不看参数代价的翻车操作。maxmemory 本身是字节数不是 key 数量。需要监控 used_memory 和 maxmemory 的比例超过 80% 就要预警扩容或者调整 key 的过期时间。3. 从单机到集群安装部署、主从复制、哨兵与分布式锁的落地步骤3.1 Windows 和 Linux 下跑通最小可用的 Redis 单机热词里redis windows 下载windows安装redismacos 安装 redis说明安装这一步就劝退了很多人。Windows 官方其实是不支持 Redis 的微软曾经维护过一个移植版本但停更在 5.0.10 左右这也是为什么很多人折腾 Windows 版 Redis 时总感觉版本落后、特性缺失。生产服务器基本都是 Linux所以我的建议是开发机用 WSL 或者 Docker 跑 Linux 容器里的 Redis服务器直接 apt/yum 安装或者二进制部署。Docker 方式是现在最通用也最不容易把环境搞乱的方案# 拉取 Redis 6.2 镜像并启动 docker run -d --name redis-dev \ -p 6379:6379 \ -v /data/redis:/data \ redis:6.2 redis-server --appendonly yes --requirepass prod123 # 进入容器验证 docker exec -it redis-dev redis-cli -a prod123 ping这里 --appendonly yes 是开启 AOF--requirepass 是设置访问密码-v 把数据目录挂载到宿主机避免容器重建丢数据。注意 docker 里跑 Redis 有个坑默认容器时区和宿主机不一致如果 Redis 日志里出现时间错位在 docker run 里加 -e TZAsia/Shanghai 解决。如果是 Linux 裸机部署常见做法是用 make 编译安装wget https://download.redis.io/releases/redis-6.2.14.tar.gz tar xzf redis-6.2.14.tar.gz cd redis-6.2.14 make -j4 make install redis-server /etc/redis.conf编译前检查 gcc 是否安装否则 make 会报 cc 命令找不到。清理环境时把 /usr/local/bin/redis-server 和 /etc/redis.conf 删掉就行这是最干净的回滚方式。3.2 主从复制配置docker-compose 拉起一主二从理解复制原理热词里docker安装redis主从redis主从说明集群搭建是高频需求。主从复制的原理一句话讲清楚从节点向主节点发送 SYNC 或 PSYNC 命令主节点生成 RDB 快照发给从节点后续所有写命令通过命令传播异步同步给从节点。这里的异步是核心关键词意味着主从之间天然存在数据延迟强一致场景不能依赖 replication。用 docker-compose 搭一主二从是最省事的version: 3.8 services: redis-master: image: redis:6.2 container_name: redis-master ports: - 6379:6379 command: redis-server --requirepass masterpass redis-slave1: image: redis:6.2 container_name: redis-slave1 ports: - 6380:6379 command: redis-server --slaveof redis-master 6379 --masterauth masterpass --requirepass slavpass redis-slave2: image: redis:6.2 container_name: redis-slave2 ports: - 6381:6379 command: redis-server --slaveof redis-master 6379 --masterauth masterpass --requirepass slavpass--slaveof 参数指定主节点的地址和端口--masterauth 是从节点连接主节点时用的认证密码。注意主节点和从节点都设置了 requirepass 时主从之间的认证走的是 masterauth不是 requirepass。这个配置里还有个容易踩的坑从节点默认是只读的slave-read-only 默认 yes所以不要在从节点上执行写操作会直接报错。启动后用 redis-cli 检查复制状态redis-cli -a masterpass info replication关注输出里的 role:master、connected_slaves:2、slave0 和 slave1 的 state 是否为 online。如果 state 是 down大概率是 masterauth 密码配置错了或者防火墙挡了从节点到主节点的端口。3.3 主从切换与哨兵Redis 6 的集群模式怎么理解很多人把哨兵和 Cluster 模式混为一谈。哨兵Sentinel解决的是自动故障转移——主节点挂了Sentinel 自动把某个从节点提升为新的主节点客户端通过哨兵获取当前主节点地址。Cluster 解决的是数据分片——每 key 通过 CRC16 算法计算哈希槽总共 16384 个槽位均匀分布到多个主节点上同时每个主节点可以挂从节点做冗余。热词里redis集群k8s redis 集群指向的都是这两个话题。如果只用主从 哨兵数据是每个节点全量一份容量受限于单机内存。用 Cluster数据被切分容量可以横向扩展。取舍在于Cluster 模式下 key 的 multi-key 操作比如 MGET 多个不同 slot 的 key会受限需要用 hash tag 把相关 key 固定在同一个 slot。Redis 7 之前的 Cluster 搭建需要集群总线端口默认 16379用 redis-cli --cluster create 命令创建集群。启动 6 个 Redis 实例3 主 3 从然后执行redis-cli --cluster create \ 192.168.1.10:6379 192.168.1.11:6379 192.168.1.12:6379 \ 192.168.1.13:6379 192.168.1.14:6379 192.168.1.15:6379 \ --cluster-replicas 1--cluster-replicas 1 表示每个主节点配一个从节点。创建过程中会打印槽位分配计划确认输入 yes 即可。注意ip 和端口中间不要有空格否则解析会出问题。集群模式下 redis.conf 至少要开启 cluster-enabled yes并且每个节点有独立的 cluster-config-file 路径。3.4 分布式锁的三种实现方式与边界为什么 SETNX 不是银弹redis分布式锁是热词里搜索意图最明确的一个。Redis 做分布式锁的经典套路是 SETNX EXPIRE但 Redis 2.6 之后官方推荐用一条命令完成SET lock:order:12345 unique_id NX PX 30000这条命令的含义是只有当 lock:order:12345 这个 key 不存在时才设置成功NX 保证原子性PX 30000 设置 30 秒过期时间。unique_id 是客户端生成的随机值用于释放锁时校验——只有持有锁的客户端才能删除锁。释放锁必须用 Lua 脚本保证比对 删除的原子性if redis.call(get, KEYS[1]) ARGV[1] then return redis.call(del, KEYS[1]) else return 0 end为什么不能直接用 redis-cli DEL因为如果锁已经过期被别的客户端获取了直接 DEL 会把别人的锁误删这会造成两个线程同时进入临界区分布式锁失效。所以释放锁必须校验 value 是否是自己的唯一标识。用 Lua 脚本执行释放锁有几种方式。如果你用的是 Lettuce 客户端用 DefaultRedisScript 封装脚本如果你用的是 Jedis用 jedis.eval() 方法。核心是把上面那段 Lua 代码通过 eval 命令传给 Redis 执行Redis 保证脚本执行期间不会穿插其他命令。这段逻辑是所有 Redis 分布式锁的基石不管是 Redisson 还是自己封装底层都是这一套。但这里要说清楚边界Redis 分布式锁在单机、主从、哨兵、集群场景下有完全不同的可靠性等级。单机 Redis 可以保证互斥性但一旦主节点宕机且未同步到从节点锁就会丢失——这就是为什么 Redis 官方文档提出了 Redlock 算法需要至少 5 个独立 Redis 节点来投票但 Redlock 本身也有争议。生产实践上如果你的业务允许锁偶尔失效比如接口幂等控制、非资金类操作单主 Redis 锁足够了如果要求绝对安全需要用 ZooKeeper 或者数据库行锁替代。Redisson 封装了看门狗机制默认情况下锁的过期时间是 30 秒如果业务执行超过 30 秒看门狗会自动续期。这个机制能避免业务还没执行完锁过期了的问题但它也意味着如果业务线程死锁或者长时间卡住锁会一直续期造成死锁。所以使用 Redisson 时要小心设置合理的 watchdog 超时。3.5 Redis Cluster 模式下分布式锁的注意点Cluster 模式下分布式锁的坑比单机多一层。假设你用 SET NX PX 在 key 所在的 master 节点上拿到了锁但下一秒 master 挂了从节点还没有同步这条命令新的 master 接管后发现这个 lock key 不存在另一个客户端也来 SET NX PX结果两个客户端同时持有锁。这个问题的本质是 Redis 主从复制是异步的锁信息可能丢失。Redlock 算法通过多数节点写入来规避这个问题但 Redlock 在 Cluster 模式下不好实现因为 Cluster 天然把 key 分布到不同节点无法像 Redlock 那样把同一个锁 key 写入多个独立节点。实操上有两个折中方案一是开启 wait 参数让写命令同步等待从节点确认但这会大幅降低性能二是引入 ZooKeeper 或者 etcd 做分布式锁对资金交易类场景更稳妥。我经常和团队说一句话Redis 分布式锁是够用但不完美的锁金钱链路不要用它裸奔。4. Redis 常见问题排查与避坑缓存穿透、序列化乱码、连接超时与内存碎片4.1 缓存穿透和缓存雪崩现象、原因、解决一条条讲透热词里redis 缓存穿透redis缓存治理redis缓存是一个家族的问题。先区分三个概念因为很多人把穿透、击穿、雪崩混在一起说缓存穿透请求的 key 在缓存和数据库里都不存在每次都打到数据库缓存击穿某个热点 key 的缓存过期大量请求同时打到数据库缓存雪崩大量 key 同时过期或者 Redis 直接宕机大量请求打到数据库穿透的解决方式是缓存空值把 null 也缓存TTL 设置短一些比如 60 秒或者用布隆过滤器在请求进入缓存前过滤掉不存在的 key。布隆过滤器在 Redis 里有专门的模块也可以自己通过 bit 数组实现。最常见的误用是只加空值缓存但没有设置短 TTL结果非法 key 的空值永远占着内存。击穿的解决方式是对热点 key 加互斥锁——让缓存失效后只有一个请求去重建缓存其他请求等待。或者干脆不设置过期时间改为后台线程主动刷新缓存。这种逻辑过期 异步刷新的方案在电商大促链路里很常用。雪崩的解决方式是 TTL 加随机抖动。如果一千个 key 都是 24 小时过期真实场景就是每小时会有整点的大批量过期数据库压力瞬间飙高。设置过期时间时给每个 key 加上一个 5-30 分钟的随机偏移。从 Redis 缓存治理的完整流程来说我一般会建议团队做三件事第一是配置 maxmemory allkeys-lru确保 Redis 不会因为内存写满而挂掉第二是开启慢日志监控slowlog-log-slower-than 10000 这个配置可以帮你看哪些命令执行时间超过 10ms第三是监控 keyspace_hits 和 keyspace_misses 两个计数器的比值命中率长期低于 80% 时就要排查是不是缓存容量不足或者热点 key 分布不均。4.2 键被打上expired标记却被访问过期策略的坑有人问过为什么设置了 TTL 的 key 还能被读到这个现象的原因在于 Redis 的过期删除策略是惰性删除 定期删除结合。惰性删除就是每次读取 key 时才检查是否过期过期了才删定期删除是每 100ms 随机抽取一批设置了 TTL 的 key 检查过期并删除。在这两种机制共同作用下一个 key 可能已经到期但还没来得及被物理删除如果恰好有请求访问它Redis 会先判断过期再返回空所以客户端看不到旧数据但 key 依然占着内存。解决内存被过期 key 占用的方法是主动扫描清理用 SCAN 命令配合游标迭代找出所有设置了 TTL 且已过期的 key手动 DEL。但生产上这不是一个很好的做法因为实时的过期清理策略在大部分场景下是够用的。真正有效的治理方式是让业务侧在写 key 时就把 TTL 设计好把过期的数据尽快不再访问而不是依赖后台清理。另一个坑如果用 LREM 或者 DEL 去删除 key是没有问题的但如果你用 TTL 命令去查一个永远不存在的 key返回 -2查一个存在但没设 TTL 的 key返回 -1这两个负数返回值经常被新手搞混。排查过期问题时先看这两个返回值再动手。4.3 序列化方式引发的乱码与兼容性问题Java 客户端必看热词里redis序列化redis连接工具指向的是客户端配置。Redis Desktop Manager、Another Redis Desktop Manager 这些可视化工具显示乱码并不一定是 Redis 出了问题而是客户端写入时的序列化器选的太随意。Java 的 Redis 客户端里Spring Data Redis 默认的 JdkSerializationRedisSerializer 会把对象序列化成二进制在可视化工具里就是 \xAC\xED\x00\x05t\x00... 这样的乱码而且二进制数据没法跨语言读取。常见做法是全局改成 Jackson2JsonRedisSerializer 或者 GenericJackson2JsonRedisSerializerkey 序列化改成 StringRedisSerializer。Configuration public class RedisConfig { Bean public RedisTemplateString, Object redisTemplate(RedisConnectionFactory factory) { RedisTemplateString, Object template new RedisTemplate(); template.setConnectionFactory(factory); // key 用字符串序列化 template.setKeySerializer(new StringRedisSerializer()); // value 用 JSON 序列化 Jackson2JsonRedisSerializerObject jsonSerializer new Jackson2JsonRedisSerializer(Object.class); template.setValueSerializer(jsonSerializer); template.setHashKeySerializer(new StringRedisSerializer()); template.setHashValueSerializer(jsonSerializer); template.afterPropertiesSet(); return template; } }这个配置里有个 Python 和 Java 互操作的问题Jackson 序列化时会把对象类型信息写进 JSON 里比如 class 字段如果 Java 写入的数据要拿给 Python 读需要关闭默认类型信息或者用统一的纯 JSON 格式。我踩过这个坑Java 写入一个 HashPython 那边读出来是一个带 class 的 dict解析了半天发现是类型注解的问题。当使用 StringRedisTemplate 存取 POJO 时要注意字符串和 JSON 互转是手动的需要自己调用 ObjectMapper不如 RedisTemplate 配置好序列化器后直接存对象方便。4.4 Redis command timed out 与 Lettuce 的坑连接池不是越大越好热词里有一条很长的redis command timed out; nested exception is io.lettuce.core.rediscommandtim...这是 Spring Boot 2.x 默认用 Lettuce 作为 Redis 客户端后的经典报错。Lettuce 基于 Netty默认是共享连接模式的一个连接被多个线程复用。如果某个操作特别慢比如 keys * 这种全库扫描会把共享连接堵住后续所有命令排队超时。解决思路是禁用共享连接或者控制连接池参数spring: redis: timeout: 3000ms lettuce: pool: max-active: 8 max-idle: 8 min-idle: 0 max-wait: -1ms shutdown-timeout: 200msmax-active 是连接池上限默认是 8。很多人以为把 max-active 调大就能解决超时但连接池超过 20 后收益递减反而因为 Netty 的线程模型导致资源竞争。真正有效的排查路径是三步第一步看慢日志确认有没有命令执行时间过长第二步看是否触发了 keys 或 smembers 这类 O(N) 操作第三步看 CPU 和内存是否到瓶颈。如果三个都排除再考虑升级到 Jedis 或者调大 timeout 做兜底。Lettuce 有一个我踩过的坑在 Spring Boot 2.3 之前Lettuce 的底层连接在 Redis 主从切换后不会自动重建会出现连接失效的报错。解决方法是用 Spring Boot 2.4 版本或者手动注册 RedisConnectionFailureListener 重建连接。4.5 内存碎片率和 RSS 高的排查方向怎么用 MEMORY 诊断热词里redis内存碎片并不是热词但它是 Redis 运维里最容易被忽视的问题。内存碎片率mem_fragmentation_ratio的计算是 used_memory_rss / used_memory。正常情况下在 1.0 到 1.5 之间。如果超过 1.5说明内存碎片较多原因可能是频繁更新、删除 keyRedis 的内存分配器 jemalloc 无法有效利用释放的空间如果小于 1.0说明开启了 swapRedis 内存被换到磁盘上了性能会暴跌。排查手段是 redis-cli 里执行 memory doctor它会给出诊断建议。碎片整理可以执行 memory purge但这只是向操作系统释放空闲页并不能解决碎片问题本身。真正有效的做法是设置 activedefrag yes配合 active-defrag-threshold-lower 和 upper 参数让 Redis 在碎片率超限时自动进行在线碎片整理。注意这个功能是 Redis 4.0 之后引入的如果你还在用 3.x只能定期重启或者扩容。4.6 慢日志、monitor 命令和 info 指标的配合使用排查 Redis 问题时不要只用一种工具。我的标准流程是先看慢日志# 设置超过 10ms 的命令记录到慢日志 CONFIG SET slowlog-log-slower-than 10000 # 查看最近 100 条慢日志 SLOWLOG GET 100然后看 info stats 里的瞬时指标redis-cli --stat这个命令每秒刷新一次会显示 hits、misses、used_memory、connected_clients 等关键指标。如果发现 connected_clients 异常高检查是否有业务代码在循环里重复创建客户端连接。如果慢日志里全是 KEYS、SMEMBERS 这类 O(N) 命令基本可以判定是代码问题需要用 SCAN 和 SORT 替代。慢日志里如果有大量的 GET 和 SET但耗时很长大概率是 Redis 本身 CPU 或 IO 满了用 INFO CPU 看 used_cpu_sys 和 used_cpu_user 是哪个进程吃掉了资源。5. 用 redis-cli 和常用运维技巧炼一套自己的指纹排查法比任何监控面板都顺手前面几章把 Redis 的原理、部署和坑讲完了最后一章分享一套我在生产环境里反复验证过的排查习惯。掌握这套方法后即使没有可视化监控大屏你也能在十分钟内定位 Redis 的常见故障。第一条习惯每次 deploy 完先执行一次INFO命令的前 20 行保存下来做基线。INFO 输出里包含 redis_version、uptime_in_seconds、connected_clients、used_memory、role 这些关键信息。等线上真的出问题时拿当前 INFO 和基线的差异就能快速定位是哪个维度发生了变化。这个习惯看起来简单但能帮你省掉大量查历史配置的时间。第二条习惯CLIENT LIST 这个命令比监控面板更有用。通过它能看到每个客户端的连接状态、空闲时间、发送和接收的字节数、最后的命令是什么。比如redis-cli CLIENT LIST | awk {print $1, $2, $4, $5, $6}如果发现某个客户端连接的空闲时间很长但占用内存很高可能是它的连接池配置不合理连接没有被及时回收。CLIENT LIST 里输出的 age连接建立时长和 idel空闲时长可以帮你判断连接池的活性如果所有连接的 idel 都接近超时时间问题大概率在客户端侧的池化管理上。第三条习惯不要去用 KEYS * 做全库扫描而是用 SCAN 代替。KEYS * 在键数量上万时会让 Redis 阻塞很长时间这个坑在 4.6 里提到过。SCAN 命令可以分批迭代每次返回一个游标继续用返回的游标调用 SCAN直到游标回到 0 表示遍历完成。比如redis-cli --scan --pattern order:* | head -1000这种方式不会阻塞可以在生产环境安全地扫描 key 前缀。第四条习惯关于 Redis 密码和权限管理。生产环境里CONFIG SET requirepass只能作为临时手段真正的做法是 redis.conf 中配置 requirepass 并配合 ACL 限制每个业务的命令权限。Redis 6 之后支持了 ACL可以给不同业务分配独立的用户和权限比如只允许某个用户执行 GET、SET、DEL不允许执行 KEYS、FLUSHALL。把这个配上能避免不少由于误操作导致的数据事故。我自己在恢复数据时用过的最有价值的技巧是把 RDB 文件备份到一个冷目录然后配合 AOF 重放来无限接近零丢失。具体做法是定期用BGSAVE生成 RDB 快照同时开启 AOF。当 Redis 宕机需要恢复时先加载最新的 RDB再重放 AOF 里 RDB 之后的所有命令。这个组合能保证绝大部分场景下不丢数据。最后一句话Redis 这套东西你把它当缓存用和当数据库用完全是两种运维心态。当缓存用保可用性、防穿透、控内存当数据库用保持久化、做备份、设计分片。我经历过一次从节点延迟导致脏读的事故之后养成了一个习惯凡是资金相关、需要强一致的链路绝不只用 Redis 单节点一定要配持久化、主从复制和定期的数据校验。希望这几章的实战思路能帮你在自己环境里少走一些弯路。本文还有配套的精品资源点击获取
返回列表