告诉大家一个秘密,,,我今天加班了……哈哈,欢迎来到-->英雄联盟

下面给大家介绍下Redis的过期策略是什么样的,持久化机制是什么样的,并且我们的配置依据是什么

Redis过期策略

Redis过期策略就是指Redis如何处理设置了过期时间的键值对。Redis的过期策略有两种:定期删除和惰性删除

定期删除

定期删除,指的是Redis默认每隔100ms就随机抽取一些设置了过期时间的key,检查是否过期,如果过期就删除。这种方式可以保证过期的key不会占用太多内

但是毕竟是随机,有些key可能还是躲过一劫,也有可能导致一些key过期后还没有被删除,或者一些不常访问的key占用内存过久。所以下面两种策略就来了

惰性删除

惰性删除,指的是当访问一个key时,Redis会检查这个key是否过期,如果过期就删除并返回空。这种方式可以保证每次访问的key都是有效的

但是也有一个问题,如果用户一直不访问那些过期的key呢?还是在那占着茅坑不拉屎,下面更优秀的来了

Redis内存淘汰机制 Redis提供了8种内存淘汰策略,可以通过配置文件或者命令行来设置。这8种策略分别是:

  • noeviction:当内存不足以写入新数据时,返回错误信息,不会淘汰任何数据
  • allkeys-lru:当内存不足以写入新数据时,在所有的key中淘汰最近最少使用(LRU)的key。
  • allkeys-random:当内存不足以写入新数据时,在所有的key中随机淘汰一个key。
  • volatile-lru:当内存不足以写入新数据时,在设置了过期时间的key中淘汰最近最少使用(LRU)的key(推荐
  • volatile-random:当内存不足以写入新数据时,在设置了过期时间的key中随机淘汰一个key
  • volatile-ttl:当内存不足以写入新数据时,在设置了过期时间的key中淘汰剩余生存时间(TTL)最短的key。
  • volatile-lfu:从已设置过期时间的数据集挑选使用频率最低的数据淘汰
  • no-enviction(禁止驱逐):禁止驱逐数据,这也是默认策略。意思是当内存不足以容纳新入数据时,新写入操作就会报错,请求可以继续进行,线上任务也不能持续进行,采用no-enviction策略可以保证数据不被丢失。

Redis持久化方式

Redis持久化方式就是指将Redis中的数据保存到硬盘中,以防止数据丢失,这也是Redis厉害的地方。

Redis支持两种持久化方式:快照(snapshotting)和追加文件(append-only file)。

快照(snapshotting)

快照持久化是指在一定的条件下,将Redis中的所有数据一次性写入到一个RDB文件中。这个条件可以是基于时间或者基于写操作的数量来触发。例如:

save 900 1 #在900秒(15分钟)之后,如果至少有1个key发生变化,Redis就会自动触发BGSAVE命令创建快照。

save 300 10 #在300秒(5分钟)之后,如果至少有10个key发生变化,Redis就会自动触发BGSAVE命令创建快照。

save 60 10000 #在60秒(1分钟)之后,如果至少有10000个key发生变化,Redis就会自动触发BGSAVE命令创建快照。

也可以手动执行SAVE或者BGSAVE命令来创建快照。SAVE命令会阻塞Redis服务器直到快照完成,BGSAVE命令会在后台执行快照操作(推荐)。

快照持久化的优点是:RDB文件紧凑,恢复速度快,适合做备份和灾难恢复。 缺点是可能会丢失最后一次快照之后的数据,而且快照过程可能会影响Redis的性能。比如设置5分钟快照一次,如果恰巧4分59秒时服务挂了,那就相当于丢了5分钟数据,对于要求严谨的业务还是不能接受的,后面我们统一介绍配置

bgsave如何执行?

用的写时复制技术

  1. bgsave 子进程运行后,开始读取主线程的内存数据,并把它们写入 RDB 文件
  2. 快照过程中,  产生的写操作会被复制一份,bgsave函数会将他读取到 RDB中

追加文件(append-only file)

追加文件持久化是指将Redis执行的每一条写命令都追加到一个AOF文件中。当Redis重启时,会通过重新执行AOF文件中的命令来恢复数据。

追加文件持久化可以通过配置文件中的appendonly参数来开启,默认为no,可以设置为yes。开启后,还可以通过appendfsync参数来设置同步频率,有三个选项:

  • always:每次写入都同步到硬盘,最安全但是性能最差,性能损耗最大

    虽然最安全,并不代表完全不丢失,写入aof文件是通过事件循环磁盘同步,即使Redis遭遇意外停机时,最多只丢失一个事件循环内的执行的数据

    数据丢失风险:几乎无(微秒级)

    appendfsync always ‌并不是每条命令都立即同步落盘‌,而是 ‌每个事件循环(Event Loop)结束时批量同步多条命令

  • everysec:每秒同步一次,折中方案。
  • no:由操作系统决定何时同步,性能最好但是风险最高

追加文件持久化的优点是数据实时性好,最多只会丢失一秒的数据,并且对Redis的性能影响小。 缺点是AOF文件会比RDB文件大,恢复速度慢,并且可能存在AOF文件过大或者写入出错的问题。

为了解决这些问题,Redis提供了AOF重写机制

AOF重写机制

重写机制是可以在不影响Redis服务的情况下,对AOF文件进行压缩和优化,去除冗余的命令。AOF重写可以通过BGREWRITEAOF命令手动触发,也可以通过auto-aof-rewrite-min-size和auto-aof-rewrite-percentage参数自动触发。

auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

上面两行配置的含义是,Redis在每次AOF rewrite时,会记录完成rewrite后的AOF日志大小,当AOF日志大小在该基础上增长了100%后,自动进行AOF rewrite。同时如果增长的大小没有达到64mb,则不会进行rewrite

重写原理:

  1. Fork 子进程:Redis 主线程调用 fork() 创建一个子进程,用于执行 AOF 重写。
  2. 子进程重写 AOF 文件:子进程读取当前数据库的所有键值对,并将其转换为最小化的命令集合,写入新的 AOF 文件。
  3. 主进程继续处理请求:主线程正常处理客户端请求,同时将新命令记录到 AOF 缓冲区和 AOF 重写缓冲区中。
  4. 合并缓冲区:子进程完成后,主线程将 AOF 重写缓冲区中的增量数据追加到新 AOF 文件,最终替换旧文件

注意:复制过程中如果有bigkey是会阻塞的

AOF重写为什么会导致主进程阻塞?

当AOF重写子进程完成AOF重写工作之后,它会向父进程发送一个信号,父进程在接收到该信号之后,会调用一个信号处理函数,并执行以下工作:

  • 将AOF重写缓冲区中的所有内容写入到新的AOF文件中,保证新 AOF文件保存的数据库状态和服务器当前状态一致。
  • 对新的AOF文件进行改名,原子地覆盖现有AOF文件,完成新旧文件的替换
  • 继续处理客户端请求命令
  • 修改 BigKey 时需复制物理内存页 → 阻塞主线程,且 BigKey 越大,阻塞时间越长

问题在于bgrewriteaof操作和主进程写AOF文件的操作两者都会操作磁盘,Redis如果网络或内存到达瓶颈可能会导致没有更多资源处理,导致阻塞

bgrewriteaof往往会涉及大量磁盘操作,这样就会造成主进程在正常写aof文件的时候,出现阻塞的情形,导致主进程阻塞

解决方案

config get *append*查询相关配置

  1. `no-appendfsync-on-rewrite`设置为yes,不进行aof文件命令追加,只放到缓冲区里,但是aof有丢失的风险
  2. 将auto-aof-rewrite-percentage参数设置为0,关闭主动重写,可以在低峰期定时手动执行bgrewriteaof命令完成每日一次的AOF手动重写
  3. 只要有bigkey,复制就会阻塞主进程,就要优化THP,优化bigkey,监控告警

AOF优缺点

优点:

  1. 数据安全性高:always模式下无数据丢失,everysec最多丢失1秒数据
  2. 容灾修复能力:可通过redis-check-aof工具修复损坏的AOF文件
  3. 操作可逆性:通过编辑AOF文件删除错误命令后重新加载恢复数据

缺点:

  1. 文件体积大:存储原始命令导致文件大于RDB快照
  2. 恢复速度慢:需逐条执行命令(混合持久化可优化)
  3. 性能消耗:高频同步策略(如always)影响吞吐量

RDB与AOF协同工作

  1. 全量+增量备份:bgsave生成全量RDB快照,AOF记录增量命令
  2. 恢复优先级:重启时优先加载AOF文件(数据更完整),无AOF时使用RDB
  3. 混合持久化:通过aof-use-rdb-preamble yes开启(4.0引入,Redis 5.0+默认启用)

关键机制详解

1. bgsave原理

  • Fork子进程:主进程创建子进程 执行持久化,避免阻塞服务
  • Copy-on-Write(COW):父子进程共享内存页,仅当父进程修改数据时复制新页,减少内存占用

2. 断电恢复策略

  • 同步策略决定数据丢失量:always无丢失,everysec最多1秒,no可能丢失30秒以上
  • 混合持久化优势:结合RDB快速加载与AOF完整性,提升恢复效率

3. 节点通信机制

  • Gossip协议:Redis Cluster使用去中心化通信,节点间交换元数据,更新延迟但扩展性强
  • 集中式管理(如ZooKeeper):适用于强一致性场景,但存在单点压力

六、存储结构与协议

  • AOF格式:基于RESP协议(REdis Serialization Protocol)的文本命令存储,结构为*参数数量\r\n$长度\r\n数据\r\n
  • RESP特性:简单、可读性强、支持二进制安全(如$6\r\nbinary\r\n)

总结建议

  • 生产环境推荐配置:appendfsync everysec + aof-use-rdb-preamble yes
  • 监控与调优:定期检查AOF文件大小,结合info Persistence命令监控持久化状态
  • 容灾备份:将AOF/RDB文件同步至异地存储(如云存储服务)

本次就介绍到这里啦,感兴趣的可以光临我的其他几篇系列文章,祝大家天天开心快乐,no bug every day!

baioqin

【深入浅出Redis 一】从版本特性到数据类型到线程模型,带你了解Redis的核心特性和应用场景!

一次redis OOM问题分析解决,rdbtools安装分析redis内存

Logo

欢迎加入我们的广州开发者社区,与优秀的开发者共同成长!

更多推荐