Redis 在生产项目里不要只当"快的 Map"用,要按场景、数据一致性、故障风险来设计。常见用法可以这样落地。
1. 最常见:缓存
典型流程:
rust
请求 -> 查 Redis -> 命中直接返回
-> 未命中查数据库
-> 写入 Redis
-> 返回结果
适合缓存:
- 用户信息
- 商品详情
- 配置信息
- 首页数据
- 字典表
- 权限信息
- 热门内容
示例:
ini
String key = "user:" + userId;
String json = redis.get(key);
if (json != null) {
return JSON.parseObject(json, UserDTO.class);
}
User user = userMapper.selectById(userId);
if (user == null) {
redis.setex(key, 60, ""); // 防缓存穿透,缓存空值
return null;
}
redis.setex(key, 3600 + randomSeconds, JSON.toJSONString(user));
return user;
生产建议:
- Key 必须有统一命名规范,例如
业务:对象:ID - 缓存对象要设置过期时间
- 过期时间加随机值,避免雪崩
- 空结果也可以短时间缓存
- 大对象不要直接塞 Redis
- 不要用
KEYS *,生产用SCAN
2. 缓存更新策略
生产中最常用的是:
先更新数据库,再删除缓存
例如:
sql
更新用户信息:
1. update mysql user set ...
2. delete redis key user:123
为什么不是直接更新缓存?
因为缓存可能有复杂结构,直接更新容易出现脏数据。删除缓存后,下一次读取会重新从数据库加载。
常见策略:
读:先查 Redis,未命中查 DB,再写 Redis
写:先写 DB,再删 Redis
更稳一点可以做:
rust
写 DB -> 删缓存 -> 延迟几百毫秒再删一次
适合对一致性要求较高的场景。
注意:Redis 缓存通常只能做到最终一致,不适合作为强一致数据源。
3. 分布式锁
在多实例部署时,本地锁失效,这时可以用 Redis 分布式锁。
常见场景:
- 防止重复下单
- 防止定时任务多实例重复执行
- 秒杀库存扣减
- 同一个资源只允许一个服务处理
- 防止缓存击穿时多个线程同时查数据库
基本命令:
sql
SET lock:order:123 uuid NX EX 30
含义:
NX:不存在才设置EX 30:30 秒后自动过期uuid:锁持有者标识
释放锁必须校验 value:
vbnet
if redis.call("get", KEYS[1]) == ARGV[1] then
return redis.call("del", KEYS[1])
else
return 0
end
生产建议:
- 不要用
SETNX后再单独EXPIRE,非原子 - 锁必须有过期时间
- value 必须唯一
- 释放锁必须用 Lua 校验
- 业务时间可能超过锁过期时间时,要考虑续期
- Java 项目可以直接用 Redisson
4. 计数器
Redis 很适合做高并发计数。
场景:
- 浏览量
- 点赞数
- 收藏数
- 登录失败次数
- 接口调用次数
例如文章浏览量:
css
INCR article:1001:view_count
生产上通常不要每次都同步写数据库,可以:
先写 Redis 计数
定时任务批量同步到 MySQL
这样可以减少数据库压力。
5. 限流
Redis 可以做接口限流。
例如:用户 1 分钟最多请求 100 次。
sql
INCR rate:user:123
EXPIRE rate:user:123 60
伪代码:
ini
String key = "rate:user:" + userId + ":" + currentMinute;
Long count = redis.incr(key);
if (count == 1) {
redis.expire(key, 60);
}
if (count > 100) {
throw new TooManyRequestsException();
}
生产建议:
- 简单限流用固定窗口
- 精准限流用滑动窗口或令牌桶
- 高要求场景建议 Lua 脚本保证原子性
6. 排行榜
用 ZSet。
场景:
- 用户积分榜
- 热门文章榜
- 游戏排行榜
- 销量榜
less
ZINCRBY rank:article:daily 1 article:1001
ZREVRANGE rank:article:daily 0 9 WITHSCORES
生产建议:
- 按天、周、月拆 key
- 定期删除历史排行榜
- 大榜单只取 Top N,不要全量拉取
- 需要持久化的榜单定期落库
7. 会话和 Token
如果是多实例服务,Session 不能只存在单机内存里,可以放 Redis。
场景:
- 登录态
- Token 黑名单
- 验证码
- 短信验证码
- 临时授权码
例如验证码:
less
SETEX sms:code:13800138000 300 123456
生产建议:
- 设置短 TTL
- Key 里不要直接暴露敏感信息,必要时 hash 手机号
- 验证成功后立即删除
- 验证失败次数也要限制
8. 消息队列
Redis 可以做轻量消息队列,但要看场景。
简单队列:
arduino
LPUSH queue:order msg
BRPOP queue:order 5
更推荐 Redis Stream:
lua
XADD order_stream * orderId 1001 status paid
XREADGROUP GROUP g1 c1 COUNT 10 STREAMS order_stream >
适合:
- 异步任务
- 低成本事件流
- 简单业务解耦
但如果是核心交易链路,通常优先 Kafka、RabbitMQ、RocketMQ,因为它们在消息堆积、重试、路由、可观测性方面更成熟。
9. 延迟任务
可以用 ZSet 实现。
sql
ZADD delay:order 1718880000 order:1001
消费者定时扫描:
arduino
ZRANGEBYSCORE delay:order 0 now LIMIT 0 100
取到后处理,再删除。
场景:
- 订单超时关闭
- 延迟通知
- 自动取消任务
生产注意:
- 要防止多个消费者重复处理
- 删除任务和处理任务要设计幂等
- 数据量很大时建议用专门的延迟队列组件
10. 防缓存击穿
热点 Key 过期时,大量请求可能同时打到数据库。
解决方式:
bash
查 Redis 未命中
尝试获取锁
拿到锁:查 DB,写 Redis
没拿到锁:短暂 sleep 后重试 Redis
伪流程:
csharp
get cache
if hit return
lock = tryLock("lock:user:1")
if lock:
query db
set cache
unlock
else:
sleep 50ms
retry cache
热点数据也可以使用:
- 永不过期
- 逻辑过期
- 后台异步刷新
11. Key 设计规范
推荐格式:
makefile
系统:业务:对象:ID:字段
示例:
vbnet
mall:user:1001
mall:product:sku:2001
mall:cart:user:1001
mall:rank:article:daily:20260620
mall:lock:order:1001
mall:rate:user:1001:202606201530
规范建议:
- 使用冒号分隔
- 避免过长 key
- 避免特殊字符
- 不要把整个 JSON 当 key
- 明确 TTL 规则
- 大 key 要拆分
12. 生产配置重点
一定要关注:
maxmemorymaxmemory-policy- 持久化策略
- 慢查询日志
- 连接数
- 客户端连接池
- 主从复制延迟
- Redis Cluster 分片
- 哨兵高可用
- 监控和告警
缓存型 Redis 常见:
maxmemory-policy allkeys-lru
更安全的通用策略:
arduino
maxmemory-policy volatile-lru
前提是重要缓存都设置 TTL。
13. 生产不要这样用
尽量避免:
- 用 Redis 当唯一数据库,除非你非常清楚持久化和恢复风险
- 生产环境执行
KEYS * - 存超大 value,比如几 MB 的 JSON
- 一个 Hash/List/Set/ZSet 里塞几百万元素
- 不设置 TTL 导致内存无限增长
- 分布式锁不设置过期时间
- 直接删除锁,不校验 value
- 把 Redis 用成核心消息系统却没有补偿机制
- 缓存和数据库一致性没有设计
14. 一个典型生产用法组合
例如电商商品详情页:
markdown
商品详情:
1. 查 Redis:mall:product:detail:skuId
2. 命中直接返回
3. 未命中查 MySQL
4. 空数据缓存 1 分钟
5. 正常数据缓存 30 分钟 + 随机秒数
6. 更新商品时:先更新 MySQL,再删除 Redis
7. 热门商品用逻辑过期 + 后台刷新
8. 浏览量用 Redis INCR,定时批量落库
9. 商品排行榜用 ZSet
10. 下单防重复用 Redis 分布式锁或数据库唯一约束
一句话总结:
Redis 在生产项目里主要承担三类角色:缓存加速、分布式协调、实时数据结构计算 。真正要用好 Redis,关键不是会 GET/SET,而是要设计好 Key、TTL、一致性、故障降级、监控和数据恢复策略。