数据在内存里,重启不就没了
Redis 是内存数据库,读写极快,但进程重启或机器断电时内存数据就没了。如果拿它当缓存,丢了可以从数据库回填;如果拿它当存数据的地方(会话、计数器、排行榜),丢了就是事故。持久化就是把内存数据以某种形式写到磁盘,重启后能恢复。Redis 提供两种主要方式:RDB 快照和 AOF 日志。
- RDB某一时刻全量数据的快照文件。
- AOF追加写命令的日志,更接近实时。
- 混合持久化RDB 全量加 AOF 增量。
- 淘汰策略内存满时按规则腾地方。
RDB 快照:定时存一份
RDB 按配置(比如 N 秒内超过 M 次写)触发,fork 出子进程把当时的全量数据写成一个紧凑的二进制文件。优点是文件小、恢复快;缺点是两次快照之间宕机,这部分新写的数据就丢了。适合对丢失容忍度稍高、追求快速恢复的场景。
AOF:每条写命令都记下来
AOF 把每一条修改数据的写命令追加到日志文件。重启时重放这些命令就能恢复数据。它通过刷盘策略控制安全与性能平衡:always 每次写都刷最安全但最慢,everysec 每秒刷一次(默认,最多丢一秒),no 交给系统。AOF 文件会越来越大,需要定期重写压缩。
# redis.conf 常用配置
appendonly yes # 开启 AOF
appendfsync everysec # 每秒刷盘
auto-aof-rewrite-percentage 100
混合持久化:两者结合
Redis 4.0 起支持混合持久化:AOF 重写时,把当前全量数据用 RDB 格式写在 AOF 文件开头,之后的增量写命令再以 AOF 格式追加。恢复时先加载 RDB 全量、再重放少量增量日志,兼具恢复快和丢失少,是现在生产的推荐做法。
内存到上限了怎么办
给 Redis 设了 maxmemory 后,写新数据时如果内存满了,就要按淘汰策略腾地方。常见策略:allkeys-lru 从所有 key 里淘汰最久没用到的(适合缓存)、allkeys-lfu 淘汰最少用的、volatile-lru 只在设了过期的 key 里淘汰、noeviction 直接拒绝写(适合当数据库用)。缓存场景一般选 allkeys-lru。
过期 key 的删除策略
设了过期时间的 key,Redis 不会立刻删。它用惰性删除(访问时才检查是否过期)加定期删除(后台随机抽查一批过期 key 删掉)结合。如果只靠惰性删除,大量过期 key 长期不访问就会占着内存,所以要配合合理的 maxmemory 和淘汰策略兜底。
持久化与性能的权衡
持久化不是越严越好。fork 子进程做 RDB、AOF 刷盘都会消耗 CPU 和磁盘 IO。主节点扛高并发时,往往把持久化从主节点摘掉、交给从节点做,主节点只负责高速读写,既安全又不拖慢性能。这也是 Redis 高可用部署里常见的分工。
落地清单
- 当缓存用可侧重 RDB,当存储用必须开 AOF。
- 生产推荐混合持久化,恢复快又丢得少。
- 缓存场景淘汰策略选 allkeys-lru。
- 主节点持久化可剥离,交给从节点做。
- 定期演练恢复,别等宕机才发现备份坏了。