Redis作为缓存的使用场景与常见问题
一、Redis作为缓存的典型使用场景
1. 热点数据缓存
- 场景:高频访问的数据库查询结果(如电商商品详情)
- 优势:通过内存读写避免频繁访问数据库,响应时间从毫秒级降至微秒级
- 实现:
SET user:1001 "{name: 'Alice', age: 28}" EX 3600
2. 会话存储(Session Storage)
- 场景:分布式系统中的用户会话共享
- 优势:比传统Cookie更安全,比数据库存储更高效
- 数据结构:String/Hash存储会话信息
3. 页面/API缓存
- 场景:缓存渲染后的HTML页面或API响应
- 技巧:配合
EXPIRE
实现自动过期,使用GETSET
保证缓存更新原子性
4. 排行榜/计数器
- 数据结构:
- Sorted Set实现实时排行榜(
ZADD leaderboard 100 "user1"
) - INCR实现原子计数器(UV/PV统计)
- Sorted Set实现实时排行榜(
5. 分布式锁
- 实现:
SET lock_key unique_value NX EX 30
- 注意点:需配合Lua脚本保证原子性,推荐RedLock算法
6. 消息队列
- 方案:使用List结构实现简单队列,Stream数据类型实现可靠消息队列
二、常见问题与解决方案
1. 缓存穿透
- 现象:大量请求不存在的key(恶意攻击/非法查询)
- 解决方案1(推荐):
-- 布隆过滤器伪代码
if not bloom_filter.exists(key) then
return null
end
- 解决方案2:
空值缓存:SET null_key “” EX 300 - 解决方案3:
接口校验:增加参数合法性验证
2. 缓存击穿
现象:热点key过期瞬间大量请求直达DB
- 解决方案1(最终一致性场景推荐):
永不过期策略 + 异步更新 - 解决方案2(强一致性场景推荐):
互斥锁:
def get_data(key):
value = redis.get(key)
if not value:
if redis.setnx("lock", 1):
redis.expire("lock", 10)
value = db.get(key)
redis.setex(key, 3600, value)
redis.delete("lock")
else:
sleep(0.1)
return get_data(key)
return value
3. 缓存雪崩
现象:大量key同时过期导致DB压力激增
- 解决方案1(推荐):
随机过期时间:EXPIRE key 3600 + random(600) - 解决方案2:
分级缓存:L1缓存(Redis)+ L2缓存(本地缓存) - 解决方案3:
熔断降级:Hystrix/Sentinel实现系统保护 - 解决方案4:
搭建集群
4. 数据一致性
挑战:缓存与数据库的同步延迟
- 策略1(最终一致性场景推荐)
延迟双删策略:
public void updateData(Data data) {
redis.del(data.id); // 第一次删除
db.update(data); // 数据库更新
Thread.sleep(500); // 等待主从同步
redis.del(data.id); // 第二次删除
}
- 策略2(最终一致性场景推荐)
订阅binlog实现异步更新(Canal框架) - 策略3(强一致性场景推荐)
适用于金融交易、库存扣减、订单状态等对数据准确性要求极高的场景,需要保证缓存与数据库的实时严格一致
同步双写 + 事务控制:
将数据库更新与缓存操作放在同一事务中
// 伪代码示例(需要支持XA事务的中间件)
@Transactional
public void updateOrder(Order order) {
// 1. 数据库更新
orderDao.update(order);
// 2. 同步更新缓存(必须与数据库操作在同一事务)
redisTemplate.opsForValue().set(
"order:" + order.getId(),
order,
30, TimeUnit.SECONDS
);
}
注意事项:
需要数据库和Redis支持分布式事务(如通过Seata框架)
性能损耗较大(较最终一致性方案吞吐量下降40%-60%)
5. 内存管理
风险:内存溢出导致服务崩溃
应对措施:
监控内存使用:INFO memory
配置淘汰策略:
maxmemory 16gb
maxmemory-policy allkeys-lru(优先淘汰最近最少使用的key)
使用内存分析工具:redis-rdb-tools分析大key
6. 集群问题
常见问题:
脑裂问题:配置min-slaves-to-write 1
数据倾斜:使用Hash Tag合理分配slot
扩容缩容:使用redis-trib工具管理集群
7. 持久化风险
方案选择:
RDB:定时快照,恢复快但可能丢失数据
AOF:日志追加,数据安全但文件较大
混合模式(Redis 4.0+):aof-use-rdb-preamble yes