Redis 持久化、key过期策略、淘汰策略

Redis为保证数据安全性提供了RDB和AOF两种持久化方案,RDB是全量快照,AOF记录写操作日志。AOF重写用于减小文件体积。当内存满时,Redis依据key淘汰策略删除部分key,如LRU。内存上限可通过maxmemory设置,过期key通过定期或惰性删除策略管理。

Redis 数据存在内存中,内存读取快但内存只是负责暂时性的存储,这理整理下Redis的持久化方案。

RDB : 在指定的时间间隔内将内存中的数据集快照写入磁盘。

  • 快照数据存储在,默认 dump.rdb 文件中

触发方式:

  • 手动触发:输入命令 save,该命令会阻塞当前Redis服务器,执行save命令期间,执行完成时候如果存在老的RDB文件,就把新的替代掉旧的。
  • 手动触发:输入命令 bgsave ,redis系统调用函数fork(),创建一个子进程将数据集写入到一个临时 RDB 文件中,完成后替换并删除旧RDB文件,操作是异步的阻塞只发生在fork阶段,一般时间很短。
  • 自动触发:修改配置文件,1,多少秒内有多少个key被更改时触发。

特点:

  • 全量备份,在大数据集恢复时,数据较快。
  • bgsave子进程生成RDB文件是,父进程数据的修改无法感知,可能造成数据丢失

AOF :以协议文本的方式,将所有对数据库进行过写入的命令(及其参数)记录到 AOF 文件.

  • 开启:配置文件中 appendonly no

触发配置:

  • appendfsync always :每次有新命令追加到 AOF 文件时就执行一次 fsync ,非常慢,也非常安全
  • appendfsync everysec :每秒 fsync 一次:足够快(和使用 RDB 持久化差不多),并且在故障时只会丢失 1 秒钟的数据。
  • appendfsync no:从不 fsync :将数据交给操作系统来处理。更快,也更不安全的选择

aof文件重写:

  • 目的:数据量过大时,aof文件体积也会越来越大,为了缓解磁盘空间压力.
  • 压缩:重写的aof文件记录的只是每个数据的最后一次写指令,也就是最新的数据,不会记录之前冗余的操作,所以这样会很大程度的缩小AOF的体量
  • 手动触发bgrewriteaof
  • 配置触发 👇
# 指当前aof文件比上次重写的增长比例大小,达到这个大小就进行 aof 重写
auto-aof-rewrite-percentage 100  

# 最开始aof文件必须要达到这个文件时才触发,后面的每次重写就不会根据这个变量了
auto-aof-rewrite-min-size 64mb  

混合持久化:新的AOF文件前半段是RDB格式的全量数据,后半段是AOF格式的增量数据

  • version >4.0

  • 开启:配置文件中,aof-use-rdb-preamble yes

  • 触发:bgrewriteaof

  • 过程: 当开启混合持久化时,fork出的子进程先将共享的内存副本全量的以RDB方式写入aof文件,
    然后在将aof_rewrite_buf重写缓冲区的增量命令以AOF方式写入到文件,写入完成后通知主进程更新统计信息,并将新的含有RDB格式和AOF格式的AOF文件替换旧的的AOF文件

  • 恢复: 在redis重启的时候,加载 aof 文件进行恢复数据:先加载 rdb 内容再加载剩余的 aof。
    2


key淘汰策略

  • 当数据集过大时,超过reids设置的最大内存,会删除掉部分key
  • 如何保持redis存储的都是有效的热点数据

内存上限设置:maxmemory <bytes>
在这里插入图片描述

key过期策略:

  • 定期删除
    指的是redis默认是每隔100ms随机抽取一些key来检查和删除的。定期删除可能会导致很多过期key到了时间并没有被删>除掉,这时候就需要惰性删除了。
  • 惰性删除
    在获取某个key的时候,redis会检查一下 ,这个key如果设置了过期时间那么是否过期了?如果过期了此时就会删除,不>会给你返回任何东西。
  • 两种结合使用,就能够保证:一个key如果过期了,肯定会被删除了

key淘汰策略:

  • 触发:内存达到上限
策略效果
noeviction -默认当内存使用达到阀值的时候,所有引起申请内存的命令会报错
allkeys-lru尝试回收,最近未使用或者使用比较少的键。(范围是:所有的键)
volatile-lru尝试回收,最近未使用或者使用比较少的键。(范围是:设置了过期时间的键)
allkeys-random随机移除某个key。(范围是:所有的键)
volatile-random随机移除某个key。(范围是:设置了过期时间的键)
volatile-ttl回收过期时间较短的key。(范围是:设置了过期时间的键)

LRU:

  • 所有缓存通过一个链表连接起来,新创建的缓存添加到链表的头部,如果有缓存被访问了,就把缓存移动到链表的头部。
    由于被访问的缓存会移动到链表的头部,所以没有被访问的缓存会随着时间的推移移动的链表的尾部,
    淘汰数据时只需要从链表的尾部开始。
<think>嗯,用户这次的问题是关于Redis策略的深入探讨,涉及拒绝策略过期策略和删除策略三者的区别和应用场景。从用户引用的资料来看,ta已经掌握了一些基础概念,但需要更系统的对比分析。 用户可能正在设计高并发系统,需要根据业务特点选择合适的Redis策略组合。ta提到“应用场景”,说明需要落地指导而非纯理论。有趣的是,ta特意区分了这三个易混淆的概念,说明之前可能遇到过策略配置不当导致的线上问题。 从技术角度看,这三个策略确实容易混淆: - 删除策略针对的是已过期的键如何清理(后台定时 vs 惰性检查) - 过期策略是键的生命周期管理方式(立即过期 vs 惰性过期) - 拒绝策略则是内存不足时的应急方案(报错 vs 淘汰数据) 用户引用的资料[1][3]提到惰性删除和定时删除,[2]提到allkeys-lru淘汰策略,[4][5]补充了Redis适用场景。需要把这些碎片信息整合成体系化的回答。 特别要注意用户上次讨论过RR隔离级别,说明ta对技术细节有钻研精神。这次回答需要保持同等专业深度,比如解释惰性删除为什么可能引发内存泄漏,或者volatile-lru在电商促销场景的应用价值。 考虑到用户连续提问数据库缓存,可能是后端开发或架构师。回答要突出实战性,比如给出“秒杀场景推荐策略组合”这样的具体建议。同时必须澄清常见误区,比如很多人认为maxmemory-priority只对设置了TTL的键生效,其实allkeys系列策略会影响所有键。</think>以下是Redis中拒绝策略过期策略与删除策略的详细对比及应用场景分析,三者共同协作保障Redis高性能与数据可靠性: --- ### **1. 删除策略过期键清理机制)** 解决核心问题:**如何清理已过期的键?** - **惰性删除(Lazy Expiration)** - **原理**:只在访问键时检查过期时间,若过期则删除 - **特点**: - ✅ CPU友好(无额外开销) - ❌ 内存不友好(未访问的过期键长期占用内存) - **场景**:读少写多的低频数据缓存 - **示例**: ```python # 伪代码:GET命令触发检查 def get(key): if redis_db[key].expire_time < now(): del redis_db[key] # 删除过期键 return None return redis_db[key].value ``` - **定期删除(Periodic Expiration)** - **原理**:定时任务抽样扫描过期键(默认每秒10次) - **特点**: - ⚖️ 平衡CPU与内存(通过调整扫描频率) - ⚠️ 可能漏删(非100%覆盖) - **场景**:通用场景的折中方案(Redis默认策略) - **立即删除(主动驱逐)** - **原理**:设置键过期时立即启动删除任务 - **特点**: - ✅ 内存最及时释放 - ❌ 高CPU开销(影响吞吐量) - **场景**:对内存敏感且可接受性能波动的场景 > 📌 **总结**:删除策略关注**物理删除时机**,确保过期数据最终被清理[^1][^3]。 --- ### **2. 过期策略(键生命周期管理)** 解决核心问题:**何时判定键过期?** - **TTL(Time To Live)** - **原理**:显式设置键的存活时间(如 `SET key value EX 30`) - **实现**: - Redis内部维护**过期字典**(expires dict)存储键->过期时间戳 - **特点**:精确控制数据生命周期 - **惰性过期(逻辑过期)** - **原理**:不主动删除键,仅在访问时判断是否逻辑“失效” - **场景**: - 允许暂时数据不一致(如缓存雪崩保护) - 结合删除策略实现物理清理 > 📌 **总结**:过期策略定义**数据有效性规则**,需依赖删除策略执行物理清理[^1][^3]。 --- ### **3. 拒绝策略(内存溢出处理)** 解决核心问题:**内存不足时如何应对新写入?** 通过 `maxmemory-policy` 配置: | 策略 | 机制 | 适用场景 | |------|------|----------| | **noeviction** | 拒绝所有写入请求(默认) | 数据绝对不可丢失场景 | | **allkeys-lru** | 淘汰最近最少使用的键 | 通用缓存(平衡热度) | | **volatile-lru** | 仅淘汰**有过期时间**的LRU键 | 缓存+持久数据混合存储 | | **allkeys-random** | 随机淘汰任意键 | 无访问规律的数据 | | **volatile-ttl** | 优先淘汰剩余存活时间最短的键 | 时效性敏感数据(如验证码) | | **volatile-lfu** | 淘汰使用频率最低的键 | 热点数据分布不均场景 | > 📌 **关键区别**:`volatile-*` 系列**只淘汰设定了TTL的键**,而 `allkeys-*` 可能淘汰任何键[^2][^3]。 --- ### **三策略协作关系** ```mermaid graph TD A[写入数据] --> B{是否设置TTL?} B -->|是| C[过期字典记录过期时间] B -->|否| D[永久存储直至内存不足] C --> E[删除策略定时/惰性清理] D --> F[内存不足时触发拒绝策略] F --> G[根据maxmemory-policy淘汰数据] ``` --- ### **典型应用场景** 1. **高频访问缓存** - **组合**:`定期删除` + `allkeys-lru` + **设置TTL** - **效果**:自动淘汰冷数据,保证热数据驻留内存 2. **会话存储(Session)** - **组合**:`惰性删除` + `volatile-ttl` - **原因**:会话自然过期优先,避免误删活跃会话 3. **实时排行榜** - **组合**:`立即删除` + `noeviction` - **原因**:数据需强一致性,宁拒绝写入也不淘汰 4. **消息队列(临时数据)** - **组合**:`定期删除` + `volatile-lru` - **优势**:平衡内存与CPU,自动清理消费后的数据 > ⚠️ **避坑提示**: > - 使用 `volatile-*` 策略时**必须设置TTL**,否则等同于 `noeviction` > - 混合存储场景慎用 `allkeys-lru`,可能误删持久化数据[^2][^4] ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值