更新:2026-09-05 16:11

缓存与性能规范

Redis 使用规范、缓存键设计、N+1 优化、列表/详情缓存策略。

1. 缓存键命名

统一前缀 + 业务 + 维度,dataprefixweb.prefix 注入:

<dataprefix>_<业务>_<主键>         如 typecho_soft_info_12
<dataprefix>_<业务>_<主键>_<维度>   如 typecho_soft_info_12_3(uid 维度)
<dataprefix>_<业务>_<page>_<limit>  列表缓存

用户态相关缓存必须带 uid:付费状态、已购状态、浏览偏好等。不带 uid 会导致 A 用户状态暴露给 B 用户。

2. 读写规范

// 写(TTL 秒)
redisHelp.setRedis(key, jsonString, 30, redisTemplate);
// 读
String v = redisHelp.getRedis(key, redisTemplate);
// 列表
redisHelp.setList(key, jsonList, 30, redisTemplate);
List l = redisHelp.getList(key, redisTemplate);
// 删单条 / 按模式删
redisHelp.delete(key, redisTemplate);
redisHelp.deleteKeysWithPattern("*" + dataprefix + "_xxx_*" + uid, redisTemplate, dataprefix);
  • TTL:详情类 30~60s、配置类更长、用户态不宜太长(余额/状态)。
  • 写后删(cache-aside):变更数据后删除对应缓存,让下次请求重建。
  • 更新表结构/数据修复后必须清相关缓存(配合管理端"清除缓存")。

3. 列表缓存与登录用户

软库/商城列表对未登录用户走共享短缓存(30s),登录用户直查库以返回个性化 isPaid 等:

if (!isAdmin && loginUid == 0) {
    // 命中缓存直接返回
}
// 否则查库 + 附加登录态字段

好处:命中率高 + 状态准确。代价:登录用户列表稍慢(可控)。

4. N+1 优化

在列表循环中批量查询关联数据,禁止逐条 selectByKey

// 收集所有 id
List<Integer> ids = ...;
// 批量查(in 查询或缓存 Map)
Map<Integer, UserInfo> map = ...;
for (item : list) { json.put("userJson", map.get(item.getUid())); }

参考:SoftController.list 的批查 userJson/honor/已购、SpaceController.spaceList 的批量关联。

5. 性能底线

  • 列表接口必须分页(limit 上限 50)。
  • 高频只读接口配短缓存;写接口防刷限频。
  • 避免大字段(正文、截图列表)在列表里全量返回——列表转发用摘要字段。
  • 服务端渲染站点(Sulo)注意 SSR 首屏数据接口的缓存友好(useAsyncData 复用)。

6. 常见坑

  • 缓存键忘加业务名 → 跨模块冲突。
  • 更新数据库后忘删缓存 → 数据回退展示。
  • 列表缓存 key 未含筛选参数 → 不同筛选串数据。
  • N+1 未优化 → 列表 N 次查询(20 条 20 次 SQL)拖垮接口。