Redis 持久化

目录

一、单点 Redis 存在问题

二、RDB 持久化

三、AOF 持久化

四、混合持久化


一、单点 Redis 存在问题

  1. 数据丢失:基于内存存储,服务器宕机 / 重启导致数据丢失
  2. 并发能力:Redis 并发虽然高但是有些场景还是不够高,比如双十一秒杀、抢票等
  3. 故障恢复:单台 Redis 故障之后导致服务不可用,要保证高可用,需要 Redis 自动故障恢复,在服务运行的过程中修复出故障的节点
  4. 存储能力:内存容量有限,单台 Redis 内存容量难以满足需求

接下来分四个章节分别讨论上述四个问题的解决方案:Redis 持久化(本章)、主从机制、哨兵机制以及分片集群

二、RDB 持久化

1、RDB:Redis Database Backup file Redis 数据备份文件 / RDB 快照,将内存中的数据写入磁盘

2、快照文件称为 RDB 文件,默认保存在 当前运行目录

redis.conf 中有一个配置,配置了 RDB 文件默认保存的位置

  • dir ./表示当前目录
  • dbfilename dump.rdb表示 RDB 文件名称
  • rdbcompression yes表示是否压缩,建议不开启,压缩会消耗 CPU,不压缩消耗磁盘没关系

3、如何开启 RDB?

  • 连接 Redis 之后执行 save 命令,但是 save 是由 Redis 的主进程来执行 RDB 的,会阻塞命令的执行
  • 后台进程执行 RDB:bgsave,开启子进程执行 RDB,避免主进程受到影响

4、RDB 的执行频率

  • 停机时 自动执行 RDB,保存在当前目录

Saving the final RDB snapshot before exiting.

运行中突然宕机不会做 RDB,需要每隔一段时间进行一次 RDB

  • 配置:保存在 redis.conf 文件中
    • save 900 1:900 秒内至少有 1 个 key 被修改,则执行 bgsave,如果是 save "" 则表示禁用 RDB
    • save 60 1000
    • save 300 10

秒数相同,修改次数越大,执行频率越低

修改次数相同,秒数越大,执行频率越低

100 秒内至少修改 10 次和 200 秒内至少修改 20 次有什么区别❓

虽然平均都是两秒一次,但是判断的时间范围不同,时间范围越大,对执行 RDB 的限制越宽容

save 10 1000:如果一直都没有 10 秒内修改 1000 次,那就一直不会执行 bgsave 吗❓所以需要配适当的时间间隔?

5、执行频率怎么配?

  • 太长:有可能丢失很多数据
  • 太短:数据量大时,频繁 RDB 性能不好
  • 默认:30s / 60s,但是还是有可能丢失数据=>AOF

6、RDB 底层原理 ✨✨✨

  • bgsave 开始时 主进程会 fork 一个后台的子进程(子进程共享主进程的内存数据),完成 fork 后由子进程读取内存数据并写入 RDB 文文件
  • 子进程共享内存:fork 子进程时会复制主进程的页表(保存了虚拟内存和物理内存的映射关系),读取数据时通过页表映射到相同的物理内存进行读取
  • 读写冲突:主进程异步执行 RDB,在子进程执行 RDB 的过程中,主进程还是可以接受客户端的请求来修改内存中的数据,造成父子进程数据不一致
  • 写时复制技术(Copy on Write):将共享内存设置为只读 read-only 的,如果父子进程任一方想要修改数据,就会进行数据拷贝,将要修改的数据拷贝一份副本,修改副本,子进程执行 RDB 读取的还是修改前的数据,主进程读取的则是修改之后的数据(页表映射改变了)
  • 极端情况:RDB 过程中,主进程把所有数据都改了一遍,则所有的共享数据都被拷贝了一份新的,Redis 对内存的占用翻倍==>RDB 前要预留一部分空间来做 RDB,否则会造成内存溢出

在此过程中主进程几乎是零阻塞的,只在 fork 子进程时阻塞一小段时间,后面的工作都有子进程去执行,所以对主进程没什么影响

7、RDB 方式 bgsave 的执行流程

  • fork 子进程,共享内存空间
  • 子进程读取内存数据,写入 RDB
  • 子进程读取完成,用新的 RDB 文件替换旧的 RDB 文件

8、写时复制出来修改的数据什么时候 RDB❓是在下一次 RDB 的时候才能得到持久化吗

9、RDB 的优缺点

  • 每次 RDB 间隔可能 导致数据丢失,存在数据安全的漏洞

减少 RDB 执行间隔?❌ 耗时⬇️

  • 耗时较长:fork、压缩、写出 RDB 文件都是比较耗时的操作

三、AOF 持久化

提高数据安全性,弥补 RDB 的缺陷

1、AOF:Append Only File 追加文件。记录 Redis 处理的 写命令,命令日志文件

2、AOF 文件格式 / 内容

  • *2:后面命令的长度
  • $6:字符个数
  • select 0:选择 0 号库

3、数据恢复:重启 Redis 服务器时读取 AOF 文件,将文件里的命令重新执行一遍

  • 相对于 RDB 直接写入数据而言,AOF 要先执行命令,效率更低

4、如何开启:修改 redis.conf 配置文件来开启 AOF appednonly yesappendfilename "appendonly.aof"

5、开启频率

  • appendfsync always:每次执行一条写命令,就立即记录到 AOF 文件(磁盘文件)中,数据安全最有保障,但是性能最差

执行命令和写入 AOF 文件都是由 主进程来完成

  • appendfsync everysec:默认方案,执行完写命令,先放入 AOF 缓冲区(写内存),每隔一秒再将缓冲区的数据写入 AOF 文件,有可能丢失 1 秒中的数据,性能和安全性都可以
  • appendfsync no:执行完写命令先放入 AOF 缓冲区,由操作系统来决定 何时写入 AOF 文件,有可能丢失很多的数据,无法预知,不安全但是性能好

为什么先执行命令再写入文件?

执行成功后代表命令是有效的,这样写入文件的命令都是可以执行的命令,不需要额外再做校验,恢复数据时读取 AOF 文件中的命令也不会出错 

6、缺点

  • 记录冗余命令占用 AOF 文件空间,AOF 是追加 操作 命令,对同一个 key 的多次读写都会被记录下来,RDB 记录的是 新值 以覆盖旧值
  • 重启时重复执行对同一个 key 的操作,浪费资源

7、AOF 重写✨

  • 解决:AOF 文件过大的问题,记录了对同一个 key 的多次写操作,但是只要记录最后一次写操作就好了
  • 实现:执行 bgrewriteaof 命令(Redis 在后台开启了独立子进程执行 AOF 重写操作),执行 AOF 重写,减少了不必要 / 没意义的冗余命令
  • 重写时机:在 redis.conf 中配置
    • auto-aof-rewrite-min-size 64mb:AOF 文件体积达到 64mb 就开始重写
    • auto-aof-rewrite-percentage 100:AOF 文件比上次的 AOF 文件增长超过了 100% 就触发重写(上次指的是❓上一次重写 AOF 的文件大小吗,那就是翻倍就重写) 

四、混合持久化

AOF 和 RDB 各有优缺点,Redis 现在采用的是混合持久化,即 RDB 和 AOF 混合使用(先 RDB 写入 AOF 文件,后面的增量命令直接以 AOF 追加到 AOF 文件中)

1、AOF 和 RDB 的对比

  • 26
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值