Redis持久化

Redis 是内存数据库,如果不将内存中的数据库状态保存到磁盘,那么一旦服务器进程退出,服务器中的数据库状态也会消失。所以 Redis 提供了**持久化功能 **!

RDB

RDB全称Redis Database Backup file(Redis数据备份文件),也被叫做Redis数据快照。简单来说就是定期把内存所有数据都记录到磁盘中。

一旦Redis实例出现故障重启,就会从磁盘中读取快照文件,恢复数据

什么是快照?可以理解成定期给当前的内存中的redis数据拍一张照,然后保存下来。

RDB触发机制

可以分为手动触发和自动触发,手动的save占用主进程,bgsave是fork一个新进程来完成快照保存,在此期间主进程通过copyonwrite的机制(类似copyonwrite的Arraylist那样),拷贝一份当前数据,在拷贝的地方进行修改,等到子进程完成磁盘写之后再进行覆盖。

自动触发写在redis.conf上,save X Y,表示在X秒内如果有Y个key修改,那么就save(注意这里触发的还是bgsave)

  • 手动触发

    用bgsave可以防止主进程被阻塞,提高效率

fork采用的是copy-on-write

  • 当主进程执行读操作的时候可以访问共享内存
  • 当主进程执行写操作的时候,则会拷贝一份数据

子进程和主线程怎么共享内存,也就是怎么让子进程知道redis的内存是那些块?通过拷贝主进程的页表(没错就是计组那个页表),这样就知道主进程占用的虚拟地址和物理地址的映射关系,从而找到这些块。

copyonwrite会将此时的共享内存变成只读,主进程来读的时候就可以直接读,写的时候拷贝一份。

  • 自动触发

    注意这里save其实也是bgsave,一般都不会影响主进程

优缺点

优点

  • 只有一个dump.rdb,方便持久化,是一个紧凑的二进制文件,恢复的时候速度也比AOF更快,在数据量大的时候更明显。
  • 实现了性能的最大化,fork子进程来完成而不影响主进程,保证了Redis的高性能。

缺点

  • 可能存在数据丢失,在两次RDB的时间里,如果出现宕机,这段时间没有写入的数据都将丢失
  • 没有办法做到秒级持久化/实时持久化
  • 对于cpu和内存的开销比较大,毕竟要fork一个新进程占用cpu,还要进行COW占用内存而,AOF主要占用的是IO资源

使用场景

  • 可以容忍数分钟数据丢失,追求更快的启动速度和恢复速度。

AOF

AOF(append only file) 持久化,采用日志的形式来记录每个写操作,追加到AOF文件的末尾。

意思就是把操作的每一条语句都记录下来,那肯定占用的空间大

Redis默认情况是不开启AOF的。重启时再重新执行AOF文件中的命令来恢复数据。它主要解决数据持久化的实时性问题。

AOF是执行完命令后才记录日志的。为什么不先记录日志再执行命令呢?这是因为Redis在向AOF记录日志时,不会先对这些命令进行语法检查,如果先记录日志再执行命令,日志中可能记录了错误的命令,Redis使用日志回复数据时,可能会出错。

正是因为执行完命令后才记录日志,所以不会阻塞当前的写操作。但是会存在两个风险:

  • 更执行完命令还没记录日志时,宕机了会导致数据丢失
  • AOF不会阻塞当前命令,但是可能会阻塞下一个操作。

这两个风险最好的解决方案是折中妙用AOF机制的三种写回策略 appendfsync:

  • always,同步写回,每个子命令执行完,都立即将日志写回磁盘。
  • everysec,每个命令执行完,只是先把日志写到AOF内存缓冲区,每隔一秒同步到磁盘。
  • no:只是先把日志写到AOF内存缓冲区,有操作系统去决定何时写入磁盘。

always同步写回,可以基本保证数据不丢失,no策略则性能高但是数据可能会丢失,一般可以考虑折中选择everysec。

如果接受的命令越来越多,AOF文件也会越来越大,文件过大还是会带来性能问题。日志文件过大怎么办呢?

AOF重写机制就是随着时间推移,AOF文件会有一些冗余的命令如:无效命令、过期数据的命令等等,AOF重写机制就是把它们合并为一个命令(类似批处理命令),从而达到精简压缩空间的目的。

AOF重写会阻塞嘛?AOF日志是由主线程会写的,而重写则不一样,重写过程是由后台子进程bgrewriteaof完成。

优缺点

优点

  • 实时持久化,数据安全,AOF持久化配置为always就可以基本上避免丢失,但是开销比较大,通常用容忍1s内丢失的everysec
  • 通过append模式写文件,那么即使中途服务器宕机,也可以尽量解决一致性问题(取决于刷盘策略)
  • 重写机制,在文件太大的时候可以压缩空间

缺点

  • 文件比RDB大,恢复时间也会慢很多
  • 启动效率低
  • 文件体积迅速变大,需要定期执行重写机制降低文件体积。

使用场景

  • 对数据安全性有较高需求的场景

Redis4.0开始支持RDB和AOF的混合持久化,就是内存快照以一定频率执行,两次快照之间,再使用AOF记录这期间的所有命令操作。