缓存键命名必须带服务标识前缀,如{service-name}:type:id;共享数据需明确读写权限;过期策略按场景区分;集群下scan需注意slot;双层缓存失效须原子化;跨服务通知禁用redis发布订阅。

缓存键命名必须带服务标识前缀
微服务里多个服务共用一个 Redis 实例时,user:123 这种裸键名极易撞车——订单服务和用户服务都可能生成它。不加隔离,删缓存、查错、监控全乱套。
实操建议:
- 所有键强制用
{service-name}:type:id格式,比如order:user:456、user:profile:456 - 服务名用小写短名(如
auth、pay),避免空格和下划线,方便命令行操作和监控识别 - 别依赖 Redis 的
KEYS扫描做清理——生产环境禁用,改用SCAN+ 前缀匹配,否则阻塞主线程
共享数据结构要区分读写权限与生命周期
多个服务读同一个缓存没问题,但谁负责写、谁负责失效,必须明确。常见错误是:A 服务更新了 product:789,B 服务却还在用旧值,或者 C 服务误删了它。
实操建议:
- 只允许单一服务拥有写权限,其他服务只读;写服务通过消息队列或事件通知变更,不鼓励跨服务直连 Redis 写
- 用不同过期策略区分场景:用户会话类用
EXPIRE,配置类用永不过期 + 主动更新,统计类用EXPIREAT对齐批处理时间点 - 避免用
HSET存跨服务共享对象——字段语义易冲突;改用 JSON 字符串 + 明确版本号字段,比如{"v":"1.2","price":299}
集群模式下 KEYS 和 SCAN 不能跨 slot 使用
Redis Cluster 把键按 CRC16 分到 16384 个 slot,KEYS * 在任意节点执行只会返回本节点的键,导致漏查;SCAN 同理,不指定 COUNT 或游标管理不当,容易重复或跳过。
实操建议:
- 运维侧统一用
redis-cli --cluster call {host}:{port} KEYS "{prefix}*遍历所有节点(注意 shell 转义) - 业务代码中禁用
KEYS,一律改用SCAN,每次调用传上一次返回的游标,直到游标为 0;前缀必须带{和}(如{user}:*)才能保证落到同一 slot - 如果真需要跨 key 关联(比如查某用户所有订单缓存),别硬扫,改用服务端聚合或在写入时维护反向索引键,如
user:orders:123存订单 ID 列表
本地缓存 + Redis 双层时,失效逻辑必须原子化
很多服务用 Caffeine 或 Guava 做本地缓存,再兜底 Redis。但更新时只清 Redis、没清本地,或清本地顺序错,就会短暂返回脏数据。
实操建议:
- 更新操作必须走统一缓存门面(facade),内部按「先删本地 → 再写 Redis → 最后发失效消息」顺序执行,缺一不可
- 本地缓存设较短 TTL(如 30s),作为兜底容错,不依赖它长期一致;Redis 键 TTL 设长些(如 2h),靠主动失效驱动
- 避免用
PUBLISH/PSUBSCRIBE做跨服务失效通知——消息可能丢失;改用可靠消息中间件(如 Kafka)或数据库 binlog 订阅,Redis 只存最终状态
最麻烦的不是怎么设前缀,而是服务间对“同一个业务实体”的键定义是否真正对齐——比如用户 ID 是字符串还是数字、是否带租户前缀、时间戳用秒还是毫秒。这些细节一旦不统一,后面所有缓存策略都会失效。










