跳到主要内容

04 性能优化与最佳实践

进阶篇最后一章:把散落在前面各章的"避坑要点"汇总成一份清单,再补充几个生产环境的实用技巧。 建议工作后回来重读本章,感受会完全不同。

1. 避免慢命令(Redis 是单线程,一条慢命令卡住所有人)

危险命令问题替代方案
keys *遍历所有 key,阻塞scan 分批遍历
flushall / flushdb清库,阻塞且毁灭性生产环境用 rename-command 禁用
hgetall / smembers / lrange key 0 -1(大 key 时)一次取几十万元素hscan / sscan / 分页 lrange
del 大key删除大集合同步阻塞unlink(异步删除)
复杂 Lua / 大事务执行期间独占拆小、控制循环次数

排查慢命令用慢查询日志

config set slowlog-log-slower-than 10000 # 记录超过 10ms 的命令
slowlog get 10 # 查看最近 10 条慢命令

2. 警惕大 Key(Big Key)

大 key 指 value 特别大的 key:如 10MB 的 String、百万成员的 ZSet/Hash。

危害:读写慢、删除阻塞、网络带宽被打满、集群下数据倾斜(某节点特别撑)。

发现

redis-cli --bigkeys # 扫描统计各类型最大的 key
memory usage somekey # 查看单个 key 的内存占用

治理思路

  • 拆分:一个百万成员的 Hash 拆成 key:0 ~ key:99 共 100 个小 Hash(按成员 hash 取模分配)
  • 压缩:JSON 先压缩再存
  • 删除大 key 用 unlink 而不是 del

预防:设计阶段就约定——单 key 的 String 不超过 10KB,集合类成员不超过 5000(经验值,非硬性)。

3. 警惕热 Key(Hot Key)

热 key 指访问量极高的单个 key(顶流明星官宣、秒杀商品)。集群再大也没用——一个 key 只在一个节点上,那个节点会被单点打爆。

方案

  • 本地缓存:热 key 在应用进程内也缓存一份(Caffeine/Guava),挡掉绝大部分请求
  • key 打散hot:key 复制成 hot:key:1 ~ hot:key:10 存到不同节点,读时随机挑一个

4. 批量操作:管道(Pipeline)

循环里逐条发命令,1 万条 = 1 万次网络往返,大量时间浪费在路上。Pipeline 把一批命令打包一次发出,性能提升可达几十倍:

# 慢:1 万次网络往返
for i in range(10000):
r.set(f"key:{i}", i)

# 快:打包发送
pipe = r.pipeline()
for i in range(10000):
pipe.set(f"key:{i}", i)
pipe.execute()

注意:Pipeline 只是省网络往返,不保证原子性(和事务、Lua 是不同的东西);一批别塞太多,几百到几千条一批合适。

5. 安全清单(云服务器必看)

裸奔的公网 Redis 几分钟就会被入侵。上线前逐项检查:

requirepass 强密码 # 1. 必须设密码
bind 127.0.0.1 内网IP # 2. 只监听内网,不暴露公网
protected-mode yes # 3. 保护模式保持开启
rename-command FLUSHALL "" # 4. 禁用危险命令
rename-command CONFIG ""
port 16379 # 5. (可选)换掉默认端口

外加:防火墙/安全组只放行内网、Redis 进程不要用 root 运行、Redis 6+ 可用 ACL 精细控制权限(acl setuser ...)。

6. 键设计与使用习惯清单

  • ✅ key 命名 业务:对象:id:属性,全项目统一
  • ✅ 缓存 key 必设过期时间,且加随机偏移防雪崩
  • ✅ 更新数据:先更新数据库,再删缓存
  • ✅ 写代码时用连接池(主流客户端默认就有)
  • ✅ 需要"判断+修改"的原子操作用 Lua
  • ❌ 不要把 Redis 当成主数据库存唯一数据(除非你非常清楚持久化的边界)
  • ❌ 不要在 Redis 里存能从数据库轻易查到、又几乎不访问的冷数据

7. 监控什么指标(了解)

info 命令能看到的关键指标:

指标含义警戒
used_memory / maxmemory内存使用率> 80% 要扩容或清理
keyspace_hits / (hits+misses)缓存命中率< 90% 说明缓存设计有问题
connected_clients连接数突增可能是连接泄漏
evicted_keys被淘汰的 key 数持续增长 = 内存不够
rejected_connections被拒绝的连接> 0 就要查

可视化监控常用:RedisInsight(官方 GUI)、Prometheus + Grafana(redis_exporter)。

8. 全教程避坑 TOP 10 回顾

  1. 生产禁用 keys *,用 scan
  2. 不带 EXset 会清掉原有过期时间(想保留用 keepttl
  3. 缓存 key 都要设过期时间,过期时间加随机数
  4. Redis 事务运行时错误不回滚,原子逻辑用 Lua
  5. List 当队列没有 ack,可靠场景用 Stream
  6. zrevrank 排名从 0 开始,展示记得 +1
  7. 分布式锁:SET NX EX + 随机 token + Lua 释放,三者缺一不可
  8. 大 key 拆分,删除用 unlink
  9. 批量写用 Pipeline
  10. 公网 Redis 必须设密码 + bind 内网

进阶篇完结!最后是随时翻阅的附录 👉 01 常用命令速查表