Redis持久化

94 阅读8分钟

Redis持久化

Redis持久化方式

  • RDB快照

    • 在默认情况下,Redis将内存数据库快照保存在名字为dump.rdb的二进制文件中

    • save 60 1000 表示60s内有1000次命令,我们关闭RDB只需要将所有的save保存注释掉即可

    • 我们还可以手动执行命令生成RDB快照,进入Redis客户端执行命令savebgsave可以生成dump.rdb,每次命令执行都会将所有Redis内存快照到一个新的rdb文件中,并且覆盖原有的rdb快照文件

    • 缺点: 如果服务器突然宕机,RDB快照会造成数据丢失

    • 问题: bgsave写时复制机制原理

      • bgsave子进程是由主线程fork生成的,可以共享主线程的所有内存数据
      • 子进程运行后,开始读取主线程的内存数据,并把它们写入RDB文件,此时如果主线程对这些数据都是读操作,那么主线程和bgsave子进程相互不影响
      • 但是,如果主线程要修改一块数据,那么这块数据就会被复制一块,生成该数据的副本,然后bgsave子进程会把这个副本数据写入RDB文件中,而在这个过程中,主线程仍然可以直接修改原来的数据
      • 如果配置自动生成rdb文件之后,后台使用的方式就是bgsave
    • save和bgsave对比

      • 命令savebgsave
        IO类型同步异步
        是否阻塞Redis其他指令否(生成子进程执行调用fork函数时会有短暂阻塞)
        复杂度O(N)O(N)
        优点不会消耗额外内存不阻塞客户端命令
        缺点阻塞客户端命令需要fork子进程,消耗内存
  • AOF

    • AOF快照功能并不是非常持久,如果Redis因为某些原因而造成故障停机,那么服务器将会丢失最近写入,且仍未保存到快照的数据
    • 从版本1.1开始,Redis增加了一种完全持久的方式;AOF持久化,将修改的每一条指令记录在文件appendonly.aof中(先写入OS Cache,每隔一段时间fsync到磁盘)
    • 对于如何打开AOF功能,可以在配置文件中加入 appendonly yes
    • image.png
  • AOF和RDB的区别

    • 持久化方式RDBAOF
      启动优先级
      体积
      恢复速度
      数据安全性容易丢数据根据策略决定

      注意:在生产环境,RDB和AOF可以都启用,Redis启动时如果既有aof文件又有rdb文件,会优先选择aof文件来恢复数据,因为aof一般来说数据更安全一点

  • Redis混合持久化

    • 当重启Redis时,我们很少使用RDB来恢复内存状态,因为会丢失大量数据。我们通常会使用AOF日志重放,但是重放AOF日志性能相对于RDB来说要慢很多,这样在Redis实例很大的情况下,启动需要花费很长的时间

    • Redis4.0为了解决这个问题,带来了一个新的持久化选项:混合持久化

    • 我们可以通过在配置文件中先开启AOF,然后在开启混合持久化

      • appendonly yes
      • aof-use-rdb-preamble yes
    • 如果开启了混合持久化,AOF在重写时,不再是单纯将内存数据转换为RESP命令写入AOF文件中去了,而是将重写这一刻前的内存做RDB快照处理,并且将RDB快照内容和增量的AOF修改内存数据的命令存在一起,都写入新的AOF文件中,新的文件一开始不叫appendonly.aof,等到重写完新的AOF文件之后才会进行改名,覆盖原有的AOF文件,完成新旧两个AOF文件的替换

    • 于是在Redis重启的时候,可以先加载RDB的内容,然后再重放增量AOF日志就可以完全替代之前的AOF全量文件的重放,因此重启效率大幅得到提升

    • image.png

数据备份策略

  • 写crontab定时调度脚本,每小时都copy一份rdb或aof的备份到一个目录中去,仅仅保留最近48小时的备份
  • 每天都保留一份当日的数据备份到一个目录中去,可以保留最近一个月的备份
  • 每次copy备份的时候,都把太旧的备份给删除了
  • 每天晚上将当前的机器上的备份复制一份到其他机器上,以防机器损坏

总结

  • RDB是某一时刻把数据全部从内存写入二进制文件中,是一个同步操作,即写RDB会阻塞其他的对内存的写操作,因而此模式比较耗时,如果在写的过程中发生宕机,会导致数据丢失

  • AOF是将每一条修改的指令写入aof文件,然后每隔一段时间刷入磁盘,

    • 而AOF有三种模式

      • 一种是每执行一条修改指令立即写入磁盘
      • 一种是每秒执行一次就写入磁盘
      • 一种是把执行时机交给操作系统来控制
    • 还可以通过配置控制aof重写,配置文件达到指定的容量或者达到原本容量的多少百分比再执行,而Redis4之后默认采用AOF模式

  • 混合持久化机制是指AOF在重写的时候,把内存数据写成RDB二进制文件中去,新的指令就以aof的格式追加到该文件后面

  • Redis的持久化机制

    • 持久化就是把内存中的数据写入磁盘中,防止服务宕机导致内存数据丢失

    • Redis主要是提供了两种持久化方式,一种是RDB方式,另外一种是AOF方式

      • RDB方式会根据指定规则将内存中的数据写入磁盘中,而AOF是每次执行完命令之后将命令记录下来,一般都会将这两种结合使用,比如混合持久化,RDB方式是Redis默认的持久化方案,RDB持久化时会将内存中的数据写入磁盘中,在指定目录下生成dump.rdb文件,当Redis重启的时候会通过dump.rbd文件进行恢复数据,可以直接通过save或bgsave指令去直接生成dump.rdb文件,而bgsave是触发RDB持久化的主流方式

        • bgsave的写时复制机制

          • bgsave子进程是由fork主线程生成的,bgsave子进程运行后会读取fork主线程中的内存数据,并把它们写入到rdb文件中,如果fork主线程对这些操作只是读操作,那么fork主线程和bgsave子进程相互不影响,如果fork主线程去修改某一块数据,那么这块数据会被复制一份生成该数据的副本,然后bgsave子进程会将这个数据副本写入rdb文件,而这个过程中,主线程仍然可以直接修改原来的数据
      • AOF方式是以独立日志的方式记录每次写命令,Redis重启时会执行aof文件中的命令来进行数据恢复,AOF的主要作用就是解决了数据持久化的实时性,并且是Redis的主流持久化方式,默认情况下没有开启AOF方式的持久化,可以通过appendonly参数启用

    • RDB和AOF区别

      • RDB恢复速度快,AOF恢复速度慢
      • RDB如果服务宕机数据会丢失,AOF数据丢失会根据策略决定
      • RDB存储的是二进制数据,AOF存储的是resp命令
      • RDB占用的体积小,AOF占用的体积大
      • RDB启动优先级高,AOF启动优先级低
    • 混合持久化方式

      • 在重启Redis的时候,我们很少使用RDB来恢复内存数据,因为会丢失大量数据,通常使用的是AOF日志存放,但是通过AOF日志来恢复内存数据相对于RDB会慢很多,所以可以采用混合持久化方式,我们可以通过先开启AOF然后再开启混合持久化,如果开启了混合持久化,会将重写前的内存数据采用RDB快照处理,而重写之后的内存数据会转化为resp命令,将它们全部放入aof文件中
    • 我们如何选择持久化方式

      • 通常来说应该同时使用两种持久化方案,来保证数据安全

        • 如果数据不敏感而且可以从其他地方重新生成,可以关闭持久化
        • 如果数据比较重要而且只能承受几分钟的数据丢失,比如缓存,只需要采用RDB方式
        • 如果是用作内存数据,要使用Redis持久化,建议RDB和AOF都开启
        • 如果只用AOF优先使用everysec的配置选择,因为它在可靠性和性能之间取了一个平衡
        • 当RDB和AOF都都开启时,Redis优先会使用AOF恢复数据,因为AOF保存的文件比RDB的更完整