Redis的持久化方式有哪些

Redis持久化有两种方式:RDB(Redis DataBase)和AOF(Append Only File)

alt text

  • RDB:RDB文件是一个经过压缩的二进制文件
  • AOF:AOF则是以追加的方式记录Redis执行的每一条写命令

Redis重启时加载持久化文件

alt text

RDB和AOF的区别

  • 文件类型:RDB生成的是二进制文件(快照),AOF生成的是文本文件(追加日志)
  • 安全性:缓存宕机时,RDB容易丢失较多的数据,AOF根据策略决定(默认的everysec可以保证最多有一秒的损失)
  • 文件恢复速度:由于RDB是二进制文件,恢复比AOF快
  • 操作的开销:每一次RDB保存都是一次全量保存,操作比较重,通常至少5分钟保存一次。而AOF的刷盘是追加操作,操作比较轻,通常设置为每一秒进行一次刷盘

RDB和AOF选哪种比较好

  • 从业务需要来看,如果我们可以接受分钟级别的丢失,可以选择RDB。如果我们尽量让数据安全,可以考虑AOF混合持久化,
  • 从持久化理论来看,始终开启快照是一个推荐,这也是官方默认开启RDB而不开启AOF

什么是AOF混合持久化

  • 使用RDB持久化函数,将内存数据写入到新的AOF文件中(数据格式也是RDB)
  • 而重写期间新的命令追加到新的AOF中(数据格式是AOF)
  • 新的AOF文件包含RDB格式和AOF格式的数据

RDB的触发时机

  • 调用save和bgsave命令
  • 根据我们的配置周期决定
  • redis关闭前
  • 主从复制第二阶段:主服务器全量复制RDB文件发送给从服务器
  • 客户点执行清空命令FLUSHALL

save和bgsave的区别

  • save:会阻塞主进程,客户端无法连接redis,等SAVE完成后,主进程才开始工作,客户端可以连接
  • bgsave:是fork一个save的子进程,在执行save过程中,不影响主进程,客户端可以正常链接redis,等子进程fork执行save完成后,通知主进程,子进程关闭。bgsave采取的是写时复制
    子进程写数据到临时的RDB文件,写完之后替换旧的RDB文件

AOF的触发时机

  • Redis关闭的时候
  • 每一次事件循环的时候
  • 通过配置指令关闭AOF的时候

AOF重写流程

  1. 子进程读取Redis DB中的数据以字符串命令的格式(也可以看作AOF格式)写入到新AOF中
  2. 如果有新数据,由主进程将数据写入到AOF重写缓冲区(aof_rewrite_buf)
  3. 当子进程完成重写操作后,主进程通过管道将AOF重写缓冲区数据传输给子进程,子进程追加到AOF文件中

AOF的不足

  1. 额外CPU的开销:
    • 如果有新数据,由主进程将数据写入到AOF重写缓冲区
    • 进程通过管道将AOF重写缓冲区数据传输给子进程
    • 子进程追加到AOF文件中
  2. 额外内存的开销:
    在重写的时候,Redis不仅将新的操作记录在原有的AOF缓冲区,还记录在AOF重写缓冲区
  3. 额外的磁盘开销:
    在重写的时候,AOF缓冲需要刷入旧的AOF日志,AOF重写缓冲也需要刷入新的AOF日志,导致在重写的时候多了一份数据

但是Redis在7.0做了优化?下一个问答

Redis7.0对AOF做了哪些优化

alt text

原来的AOF重写缓存被移除,采用
MP-AOF(Multi Part AOF),即多部件AOF。将原来的一个AOF变成了多个AOF,由manifest(追踪管理AOF文件)来管理。重写的时候还是fork一个子进程来对Base AOF重写

  • Base AOF:重写之前的命令
  • Incr AOF:追加新的命令

AOF缓冲区和AOF重写缓冲区的区别

  • AOF缓冲区:是正常使用AOF作为数据落地中间地带,所有的数据先到AOF缓冲区再到AOF文件中。
  • AOF重写缓冲区:是AOF重写时,redis还要继续接收数据,这个数据就写到AOF重写缓冲区,当AOF重写ok时,主进程在把AOF重写缓冲区的数据写到AOF缓冲区,最后fsync到AOF文件中