缓存优化L1L2

public User getUser(Long id) {
// 1️⃣ 查 L1
User user = localCache.getIfPresent(id);
if (user != null) {
return user;
}

// 2️⃣ 查 L2
user = redisTemplate.opsForValue().get("user:" + id);
if (user != null) {
localCache.put(id, user);
return user;
}

// 3️⃣ 查 DB
user = userMapper.selectById(id);
if (user != null) {
redisTemplate.opsForValue().set("user:" + id, user, 30, TimeUnit.MINUTES);
localCache.put(id, user);
}

return user;
}

L1 的核心作用:

  • 减少 Redis QPS

  • 降低网络 IO

  • 热点 Key挡在 JVM 里

L1 = 加速层
L2 = 事实缓存层

✅ 非常适合 L1 的场景

  • 登录用户信息

  • 租户信息

  • 权限 / 菜单

  • 字典数据

  • 热点配置

❌ 不适合 L1 的场景

  • 强一致性(余额、库存)

  • 超大对象

  • 低频访问

L1:localCache // JVM 内存(Caffeine / Guava / Map)
L2:Redis // 分布式缓存
L3:DB // 数据库

👉 缓存失效策略

权限变更 = 缓存失效,而不是缓存更新

1️⃣ 更新数据库(最终真相)
2️⃣ 删除 Redis(L2)
3️⃣ 删除本机 L1(可选 / 本地)

@Transactional
public void updateUserPermission(Long userId, List<Role> roles) {
// 1. 更新数据库
userMapper.updateUserRoles(userId, roles);

// 2. 删除 L2(所有节点都会 miss)
redisTemplate.delete("user:" + userId);

// 3. 删除本机 L1
localCache.invalidate(userId);
}

 

2️⃣ Redis Key 要有版本意识(进阶)

"user:v1:" + id

权限模型大改时,直接升版本,全量失效

用户权限变更时:

  • ✅ 更新 DB

  • ✅ 删除 Redis

  • ✅ 本地 L1 要么删、要么靠 TTL 自愈

  • ❌ 不要主动回填多级缓存

 

 

 

 

 

posted @ 2025-12-19 00:11  白玉神驹  阅读(3)  评论(0)    收藏  举报