Redis持久化问题

4 阅读4分钟

Redis 缓存机制与实战避坑指南

一、 核心概念:Redis 是什么?

Redis 是一个基于内存的高性能键值对(Key-Value)数据库。

  • 优势:读写速度极快(微秒级),适合做缓存。
  • 劣势:内存断电即失,数据易丢失。
  • 定位:在 Java 项目中,通常作为 MySQL 的“前置缓存”,减轻数据库压力。

二、 核心机制:缓存读写流程(Cache-Aside Pattern)

当程序需要读取配置或数据时,遵循以下标准流程(以若依框架的 selectConfigByKey 为例):

  1. 先查缓存:程序先去 Redis 里找对应的 Key。
  2. 命中缓存:如果 Redis 里有,直接返回,绝对不看数据库
  3. 未命中缓存:如果 Redis 里没有(Key 不存在或已过期),程序会去 MySQL 数据库查。
  4. 回写缓存:从 MySQL 查到数据后,程序会顺手把数据写回 Redis,方便下次查询。

实战启示:当你修改了数据库,但没更新 Redis,程序永远读的是 Redis 里的旧值。这就是“改库不生效”的根本原因。


三、 缓存更新策略:为什么页面修改能生效,改库不生效?

操作方式底层逻辑是否生效
通过系统页面修改执行 updateConfig 方法,同时更新 MySQL 和 Redis✅ 立即生效
直接修改 MySQL 数据库只更新了 MySQL,Redis 里的旧值依然存在❌ 不生效
重启 Redis如果开启了持久化,Redis 会把硬盘上的旧数据重新加载回内存。❌ 通常不生效
重启 Java 后端会触发 resetConfigCache 逻辑,清空并重新加载所有配置到 Redis。✅ 生效
手动 DEL 缓存 Key精准删除 Redis 里的脏数据,下次请求会自动去 MySQL 查最新值并回写。✅ 立即生效

四、 持久化机制:为什么重启 Redis 没用?

Redis 为了防止数据丢失,默认开启了持久化(RDB),它会把内存里的数据保存到硬盘上。

  • dump.rdb 文件:Redis 的“存档文件”。
    • 关闭 Redis 时:Redis 会把内存里的数据(包括错误的旧值)存入 dump.rdb
    • 启动 Redis 时:Redis 会读取 dump.rdb,把旧数据原封不动地恢复到内存里。
  • 结果:你重启了 Redis,但缓存里的旧值又回来了,问题依旧。
  • 如何彻底清空:在 Redis 关闭状态下,去 D:\Redis\ 目录删掉 dump.rdb 文件,再启动 Redis,它就会以空内存运行。

注意:生产环境不能随便删 dump.rdb,会导致用户掉线、缓存雪崩。


五、 实战避坑:如何正确修改 Redis 里的配置?

错误姿势:

  • 直接改 MySQL 数据库,指望 Redis 自动同步。
  • 直接重启 Redis,指望清空缓存。
  • 直接删除 dump.rdb(生产环境禁止)。

正确姿势(推荐按顺序):

  1. 改数据库:确保改的值格式正确(如全小写 true)。
  2. 精准清缓存:打开 Redis 客户端,执行 DEL sys_config:sys.account.captchaEnabled
  3. 刷新页面:重新发起请求,程序会自动去 MySQL 查最新值并写入 Redis。

六、 高级技巧:关闭持久化(仅限开发环境)

如果你在本地开发,每次改完库都要手动删缓存太麻烦,可以直接关闭 Redis 持久化,让 Redis 变成纯内存缓存。

命令行启动方式

redis-server.exe --save "" --appendonly no
  • --save "":禁用 RDB 快照。
  • --appendonly no:禁用 AOF 日志。

修改配置文件: 在 redis.windows.conf 中修改:

save ""
appendonly no

启动时带上配置文件:redis-server.exe redis.windows.conf

关闭持久化后:Redis 一关,数据全没,重启就是空内存,下次请求会自动去 MySQL 查最新数据。

警告:生产环境绝对不能关闭持久化,否则 Redis 一挂,所有用户掉线,请求会瞬间击垮 MySQL。


七、 常见问题排查清单(FAQ)

Q1:改了数据库,接口返回旧值,怎么办?

  • 检查 Redis:去 Redis 查对应的 Key 是否存在,值是否正确。
  • 手动清除:执行 DEL 对应的key
  • 再次测试:刷新页面,看是否生效。

Q2:Redis 里的值为什么带双引号(如 "false")?

  • 这通常是序列化问题(如 Jackson 序列化把字符串转为 JSON 格式)。
  • 如果代码比较逻辑是 "true".equals(value),那么 "false" 带引号会导致判断失败,需要修改序列化配置或代码逻辑。

Q3:为什么重启 Redis 不生效,重启 Java 后端就生效?

  • 重启 Redis:如果开了持久化,旧数据会恢复;如果没开,数据会清空,但程序启动时可能会重新写入旧值(取决于代码逻辑)。
  • 重启 Java:会触发启动初始化逻辑(如 @PostConstruct),强制从 MySQL 重新加载所有配置到 Redis。

八、 总结:记住这三句话

  1. 页面改配置:走的是 updateConfig,会同步更新 Redis
  2. 直接改数据库:只改了 MySQL,Redis 不知道,所以不生效。
  3. 清缓存的正确方式:精准 DEL 对应的 Key,不要盲目重启 Redis

这份文档涵盖了你在实际开发中遇到的 Redis 缓存核心问题,建议保存下来,以后遇到类似问题直接翻看,能帮你省下大量排查时间。