Skip to main content
Documents
Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage

Redis 最佳实践

1. Key 设计最佳实践

1.1 Key 命名规则(强制)

系统:业务:实体:id:字段

示例:

user:info:1001
order:detail:20240101:9981
product:stock:sku123

优点:可读、可搜索、可分层。

1.2 禁止使用过长 key

  • 推荐:20~40 字符以内
  • 避免:超过 128 字符

否则网络传输成本会被放大。

2. 避免大 Key(生产最容易踩的坑)

危险的大 Key:

  • Hash 有 10 万字段
  • List 长度 100w+
  • Set / ZSet 100w+
  • String 大于 5MB

风险:

  • 删除阻塞 Redis
  • 内存涨幅不稳定
  • 复制延迟骤增

解决方案:

  • 拆分成多个 key(hash 分片)
  • 使用 UNLINK 异步删除
  • 使用 SCAN 代替 SMEMBERS / HGETALL

3. 所有缓存都必须有 TTL(核心)

永远不要存永久 key!

推荐策略:

  • 普通缓存:随机 TTL(防雪崩)
  • 用户数据:30 分钟~2 小时
  • 配置信息:5 分钟~1 小时
  • 会话 token:30 分钟~12 小时

加随机偏移:

ttl = base + random(30~300)

4. 避免缓存雪崩 / 击穿 / 穿透(核心)

4.1 缓存穿透 -> 查询不存在的数据

解决:

  • 布隆过滤器(推荐)
  • 存空值 TTL=30s

4.2 缓存雪崩 -> 大量 key 同时过期

解决:

  • TTL 加随机
  • 预热
  • 多级缓存

4.3 缓存击穿 -> 热点 key 过期瞬间被打爆

解决:

方案一:互斥锁(推荐)

setnx(lock)
query db
set cache
del lock

方案二:永不过期 + 后台线程异步刷新(最稳定)

5. Redis 分布式锁最佳实践(强一致)

使用 SET NX EX 实现:

SET lock_key unique_value NX EX 30

释放锁使用 Lua 脚本(必须原子):

if redis.call("get", KEYS[1]) == ARGV[1] then
    return redis.call("del", KEYS[1])
else
    return 0
end

重要:

  • value 必须唯一(UUID)
  • 不能误删别人的锁
  • 不要用 RedLock(复杂、也不绝对可靠)

6. 计数器使用 INCR,不要 GET+SET

INCR view:article:1001

两段式 GET -> 修改 -> SET 会并发错误。

7. Redis 作为队列的最佳实践

推荐使用 Stream(生产最佳),不要用 List

为什么不用 List?

  • 没有 ACK
  • 没自动持久化
  • 消费失败容易丢数据

Stream 优势:

  • 消费组
  • ACK
  • 可追溯
  • 可水平扩展

8. 哈希结构(hash)最佳实践

适用于对象:

user:info:1001 -> { id, name, age }

注意:

  • 字段不要超过 5000
  • 适合小对象,不适合大对象
  • 避免 HGETALL,改用 HMGET

9. Sorted Set(ZSet)最佳实践

常用于排行榜、延迟队列

延迟队列示例:

ZADD delay_queue timestamp order_id
ZRANGEBYSCORE delay_queue 0 now

任务完成后删除:

ZREM delay_queue order_id

10. Session / Token 存储最佳实践

存储方式:

session:user:1001 -> token
token:xxxx -> user_info

注意:

  • 设置 TTL
  • 退出登录时删除 token
  • 使用 Pipelining 批量操作提升性能

11. 使用 Pipeline 批量操作(高性能)

例如批量写 100 条 key:

pipe = redis.pipeline()
for i in range(100):
    pipe.set(f"user:{i}", i)
pipe.execute()

使用场景:

  • 批量写入
  • 批量读取

不适合:复杂逻辑、依赖执行顺序的逻辑

12. 避免使用危险命令(务必重命名)

在 redis.conf:

rename-command FLUSHALL ""
rename-command FLUSHDB ""
rename-command KEYS ""
rename-command CONFIG ""
rename-command SHUTDOWN ""

13. 使用 SCAN 代替 KEYS(必须)

不要:

KEYS user:*

会阻塞整个实例!

要用:

SCAN 0 MATCH user:* COUNT 1000

14. Redis 内存限制与淘汰策略(必须配置)

maxmemory 4gb
maxmemory-policy allkeys-lru

理由:

  • 防止 OOM
  • Redis 做缓存时 LRU 效果最佳

15. Redis 的持久化策略(最佳使用方式)

最佳实践:启用混合持久化(默认)

RDB + AOF(选 everysec 选项)

appendfsync everysec
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

好处:

  • 可靠性强
  • 启动快
  • 日志不会无限膨胀

16. 主从复制最佳实践

  • 开启复制 backlog(断点续传)
repl-backlog-size 64mb
  • 主库禁用大 key
  • 主从带宽足够
  • 使用客户端读写分离(只读从库)

17. Redis Cluster 最佳实践

集群规模推荐:

3 主 + 3 从(6 节点)

最佳 key 设计:

user:{1001}:info

{} 内的内容用于 hash slot 固定。

18. Redis 性能优化(最重要的一段)

禁止:

  • KEYS、HGETALL、LRANGE 全量
  • 大 key 操作(>5MB)
  • 大列表一次性 LRANGE(需分段)
  • Lua 脚本过长运行(超过 5 秒会阻塞)

必须:

  • TTL + 随机
  • 拆分大 key
  • 使用 Pipeline
  • 使用多级缓存(本地 cache + Redis)

19. Redis 的故障排查(核心)

1. CPU 100%

  • 使用 KEYS
  • 大 key
  • Lua 脚本卡死
  • 复制积压

2. 内存暴涨

  • 没 TTL
  • key 太大
  • 数据结构过大(List/Set)

3. 主从延迟

  • 主库压力大
  • 全量同步频繁
  • 网络瓶颈

4. 连接数暴涨

  • 客户端连接未复用
  • 未使用连接池

20. 开发规范(可直接纳入项目制度)

  1. 所有缓存必须有 TTL
  2. 所有访问 Redis 的业务封装 SDK
  3. 不允许使用 KEYS / FLUSHALL / FLUSHDB
  4. 所有大 key 定期扫描
  5. 限流必须用 Lua
  6. 分布式锁必须用 SET NX EX + Lua
  7. 队列必须用 Stream
  8. 所有 Redis 命令响应时间 > 5ms 记录慢日志

🚀 Redis 生产环境最佳实践(完整指南)

🔥 目录

  1. 架构与部署
  2. 配置优化
  3. 性能优化
  4. 安全加固
  5. 内存管理与数据淘汰
  6. 备份与恢复
  7. 高可用方案推荐
  8. Python 生产级用法
  9. Kubernetes 部署最佳实践
  10. 常见坑与防踩坑指南

1. Redis 架构与部署

✅ 建议至少使用 主从 + 哨兵(Sentinel) 或 Redis Cluster

推荐结构:

场景 推荐架构
中小项目、高读写 Master + Slave + Sentinel
大规模、高并发、分布式缓存 Redis Cluster(3 主 3 从)
超大 KV 数据、水平扩展 Redis Cluster
延迟队列、多消费者 Redis Stream

2. Redis 配置优化(必须设置)

设置最大内存(非常关键)

maxmemory 4gb
maxmemory-policy allkeys-lru

禁用危险命令

rename-command FLUSHALL ""
rename-command FLUSHDB ""
rename-command CONFIG ""

开启 AOF(更安全)

appendonly yes
appendfsync everysec

RDB 建议配置

save 900 1
save 300 10
save 60 10000

禁用 swap(Linux)

sudo swapoff -a

3. 性能优化

使用内存优化数据结构

  • 哈希、集合、多字段结构 使用 HASH
  • 大列表改用 Redis Streams(更稳定)

避免 大 key

大 key 问题=阻塞 Redis + CPU 爆炸

例如:

  • 一个 List 保存 100 万行
  • 一个 key 存储 10MB JSON

检查大 key:

redis-cli --bigkeys

避免 O(N) 慢命令

高危命令:

命令 风险
KEYS * 阻塞服务器
SMEMBERS 集合超大时危险
LRANGE 0 -1 列表过长时危险
HGETALL 字段太多危险

⚠️ 禁止 KEYS

使用 SCAN 替代:

for key in r.scan_iter("user:*"):
    print(key)

4. 安全加固

密码保护

requirepass your_password_here

只监听内网

bind 127.0.0.1
protected-mode yes

禁止公网直接访问(必须)

使用 Nginx、VPC、K8s ClusterIP 隔离。

5. 内存管理与数据淘汰策略

最推荐策略:allkeys-lru

maxmemory-policy allkeys-lru

策略说明:

策略 推荐
noeviction ❌ 容易写失败
volatile-lru 不推荐
allkeys-lru ⭐ 正常缓存最佳选择
allkeys-random 备用
volatile-ttl 适合 TTL 类场景

6. 备份与恢复

AOF 备份

cp appendonly.aof appendonly.aof.bak

RDB 备份

cp dump.rdb dump.rdb.bak

自动备份设置(推荐)

Crontab:

0 */1 * * * cp /data/dump.rdb /backup/redis-$(date +\%Y\%m\%d\%H).rdb

7. 高可用方案(必须选择一个)

方案 1:主从 + 哨兵(最适合中小项目)

master
 ├─ slave1
 ├─ slave2
sentinel x 3

方案 2:Redis Cluster(适合大规模)✅

  • 支持自动分片 + 扩容
  • 最常见配置:3 主 3 从

8. Kubernetes 中 Redis 最佳实践(你的环境)

StateFulSet 部署

  • 使用 local-path / PVC
  • 每个节点固定调度

readinessProbe / livenessProbe

livenessProbe:
  exec:
    command: ["redis-cli","ping"]
  initialDelaySeconds: 15
  periodSeconds: 10

设置资源限制

resources:
  limits:
    memory: "4Gi"
    cpu: "1"

禁用 overcommit

避免 OOMKill

9. 常见坑与解决方案

问题 原因 解决
Redis 突然卡死 使用 KEYS、大 key、慢命令 改用 SCAN、拆分大 key
内存增加不下降 内存碎片 重启 Redis 或使用 jemalloc
主从延迟 网络/大 key 避免大 key,拆分结构
CPU 飙高 大量 JSON、Lua 脚本 使用哈希或 RedisJSON
Python 卡住 未使用连接池 使用 ConnectionPool