每日八股——Redis(3)

持久化机制有哪些

RDB(Redis DataBase)------快照

RDB就是 Redis定期 在某一时刻,把内存中的所有数据序列化成一个二进制文件,保存到磁盘。Redis主进程调用fork(),然后使用子进程的 bgsave 命令执行,这样不会阻塞主进程(写时复制技术,当主进程修改某个内存时,OS才会把这块内存复制一份给主进程修改,子进程依旧是读取旧的数据写入磁盘)。子进程负责把当前内存数据写入RDB文件,主进程继续处理客户端请求,写完后,用新RDB文件原子替换旧文件 。

优点

  • 文件紧凑:二进制文件,体积小,适合全量备份。
  • 恢复速度快:重启时直接加载RDB文件,比回访AOF命令快得多。

缺点

  • 数据丢失风险大:因为是定时触发,如果中间宕机,那这保存间隔内的数据将全部丢失。

AOF(Append Only File)------追加日志

AOF 就像是记日记 。它把 Redis 执行过的所有写操作命令 (如 SET, INCR)按顺序追加到文件中(默认名为 appendonly.aof),重启时通过重放日志恢复数据。

AOF不是每条命令都直接写盘(太慢),而是先写到内核缓冲区,由策略决定何时刷盘(fsync):

  1. appendfsync:每次写都刷盘,数据最安全,但性能最差
  2. appendfsync everysec(默认):每秒刷一次盘,最多丢失一秒数据
  3. appendfsync no:Redis不管,让操作系统自主决定什么时候刷盘,性能最好,但不可控。

优点

  • 数据安全:默认每秒刷盘,最多只丢失一秒数据

缺点

  • 文件体积大:通常比RDB大
  • 恢复速度慢:重启时要像重放电影一样执行一遍所有命令

AOF重写

日志文件会越来越大,比如对count加了100次1,那AOF会存100条INCR命令,但恢复其实只要一个SET count 100就好了,为了解决这个问题,Redis后台(bgrewriteaof)会自动内存中的数据,生成一个新的AOF文件,只保留构建当前数据所需的最小命令集,然后替换旧文件。

混合持久化

Redis 4.0引入,RDB恢复快但丢失数据,AOF安全但恢复速度慢,于是将他们结合起来。

原理

  • 在进行AOF重写时,Redis不再单纯把命令写入AOF文件
  • 而是先把当前内存里的数据生成RDB快照,放在AOF文件头部
  • 重写期间产生的新增命令,以AOF格式追加在文件的尾部。

当 Redis 通过 AOF 文件恢复数据时,会先加载 RDB,然后再重新执行指令恢复后半部分的增量数据,这样就可以大幅度提高数据恢复的速度了。

优点:恢复速度快,数据丢失少

Redis过期清除策略

Redis 采用的是:惰性删除 + 定期删除相结合的策略。

惰性删除------被动触发

Redis不会在Key到期那一刻立马去删他,只有当访问某个Key时,Redis才会检查这个Key是否过期,没过期正常返回,过期了就立刻删除并返回不存在。

优点:节省CPU,只有真正需要数据的时候才会去检查,不会浪费CPU资源去删除那些没人查的冷数据

缺点:浪费内存资源,如果一大堆Key已经过期了,但是永远没人去查,他们就一直在内存里,导致内存被大量无效数据占用。

定期删除------主动删除

为了解决惰性删除的内存泄露问题,Redis会隔一段时间就随机抽取一些设置了过期时间的Key,检查是否删除。这里有一个核心判断:Redis抽取的Key中,如果超过25%过期,Redis会认为过期键比例高,会再次抽取,直到过期比例下降。

优点:释放内存,能够清理掉那些没人查的冷数据,保证内存不会被垃圾填满

缺点 :销毁CPU,如果过期键太多,Redis会频繁删除,占用主线程CPU,导致处理业务速度变慢。

Redis的内存淘汰机制

Redis 的内存淘汰机制是指当 Redis 使用的内存超过 maxmemory 限制时,通过配置的淘汰策略,选择一部分 key 删除,以防止进程继续占用内存甚至被 OOM kill。

在面试中,不要死记硬背那 8 种策略,要学会**"拆解组合"**。所有的策略其实就是 2 个维度 的排列组合:

  1. "从哪里挑?" (范围) :是 所有 Key (allkeys) 还是 设置了过期时间的 Key (volatile)
  2. "按什么规则踢?" (算法) :是 LRULFU随机TTL 还是 不踢

Redis 4.0 之后,一共有 8 种策略。我们可以把它分为 4 大类

不淘汰(默认策略)

noeviction

  • 机制:内存满了直接报错OOM command not allowed,拒绝写入新数据,但允许读
  • 场景:你需要保证数据完整性,不能随便丢,通常用于把Redis当数据库用

LRU------最近最少使用

  • allkeys-lru(最常用)
    • 机制:从所有key中,淘汰那个最近最少使用的
    • 场景:缓存场景首选
  • volatile-lru
    • 机制: 只从 设置了 TTL 的 Key 中,淘汰最近最少使用的
    • 场景: 当你有些数据是持久化的(没设 TTL),有些是缓存的(设了 TTL),只想淘汰缓存数据时。

LFU------最不常用(Redis4.0)

  • allkeys-lfu
    • 机制:从所有Key中,淘汰访问频率最低的
    • 场景:针对热点数据更有效
  • volatile-lfu
    • 机制:只从设置了TTL的Key中淘汰访问频率最低的

Random随机&TTL快过期的

  • allkeys-random:从所有Key里随机删除一个
  • volatile-random:从设置TTL的key里随机删除一个
  • volatile-ttl"从设置TTL的key里,挑选TTL最短的Key淘汰
相关推荐
这个DBA有点耶5 小时前
DBA的AI助手:向量检索与NL2SQL入门
数据库·人工智能·postgresql·学习方法·dba
㳺三才人子6 小时前
初探 Flask
后端·python·flask·html
星栈独行6 小时前
我在 Rust 全栈项目里用 JWT 做无状态认证
开发语言·后端·rust·前端框架·开源·github·web
Java爱好狂.6 小时前
Java程序员体系化学习路线(2026最新版)
java·后端·java面试·java架构师·java程序员·java八股文·java学习路线
陈随易6 小时前
Redis 8.8发布,一定要更新
前端·后端·程序员
basketball6166 小时前
SQL 常用数据格式化操作方法总结
数据库·sql
装不满的克莱因瓶7 小时前
SpringBoot 如何将 lib 目录中jar包打包进最终的jar包里面
spring boot·后端·maven·jar·mvn
TE-茶叶蛋7 小时前
数据库-引用完整性(referential integrity)
数据库
IronMurphy7 小时前
MySQL拷打第二讲
数据库·mysql
ltl7 小时前
Transformer 原论文实验结果:为什么 28.4 BLEU 足以改写路线图
后端