Redis持久化(RDB和AOF)

目录

方式一:RDB

方式二:AOF

AOF重写可能出现的问题及解决方案

方式三:RDB-AOF混合持久化


Redis持久化:Redis是基于内存数据库,宕机后和数据会消失,当Redis用作DB 时,DB数据要完整,所以一定要有一个完整的数据源文件,在系统启动时,从这个完整的数据源中将数据load到 Redis内存中,完成提供持久化机制。

redis持久化方式:RDB、AOF、RDB-AOF混合持久化


方式一:RDB

RDB:在指定的时间间隔内,形成当前数据集的时间点快照。将快照信息保存到磁盘的RDB文件中。

自动触发RDB:

        在redis.conf中有如下配置,配置 save 参数即可自动触发rdb,一般RDB快照信息保存在dump.rdb文件中,文件名可以修改。

# Unless specified otherwise, by default Redis will save the DB:
 429 #   * After 3600 seconds (an hour) if at least 1 change was performed
 430 #   * After 300 seconds (5 minutes) if at least 100 changes were performed
 431 #   * After 60 seconds if at least 10000 changes were performed
 432 #
 433 # You can set these explicitly by uncommenting the following line.
 434 #
 435 # save 3600 1 300 100 60 10000

#情况1:五秒内若有两次修改,生成rdb文件

#情况2:超过五秒,生成rdb文件
 436 save 5 2

手动触发RDB:save 和 bgsave 命令

save:在主程序中执行会阻塞当前redis服务器,在执行save命令期间,不能执行其他命令,直到持久化工作完成。

bgsave:fork 出一个子进程,在后台异步进行快照操作,不会阻塞主进程。

RDB优势:

  1. RDB可以最大化redis的性能,父进程在保存RDB文件的时候唯一要做的就是fork出一个子进程,由子进程完成接下来的操作。
  2. RDB文件是经过压缩的二进制文件,占用空间很小,它保存了redis某个时间点的数据集,很适合做备份
  3. 适合大规模的数据恢复
  4. 按照业务定时备份
  5. 对数据的完整性和一致性要求不高
  6. RDB文件在内存中的加载速度要比AOF快得多

RDB劣势:

  1. 在一定时间间隔后做一次备份,如果redis在这段时间内宕机的话,这段时间的数据并没有保存快照,就会丢失从当前至最后一次保存快照期间的数据。设置save 5 2,如果五秒内没有两次修改,那要在五秒之后才生成dump.rdb文件,若是在这五秒内redis宕机的话,最多会丢失五秒内的数据。
  2. 内存数据的全量同步,如果数据量太大的话会导致I/O严重影响服务器的性能。
  3. RDB依赖与主进程的fork,在更大的数据集中,这可能会导致服务器请求的瞬间延迟,fork的时候内存中的数据被克隆了一份,会导致两倍的膨胀性,刚 fork 时,主进程和子进程共享内存,但是随着主进程需要处理写操作,主进程需要将修改的页面拷贝一份出来,然后进行修改。极端情况下,如果所有的页面都被修改,则此时的内存占用是原先的2倍。

哪些情况下会触发RDB?

  1. 配置文件中默认的save配置
  2. 手动触发
  3. 执行flushdb/flushall命令也会产生dump.rdb文件,只不过是空的
  4. 执行shutdown且没有开启AOF持久化
  5. 主从复制,主节点自动触发

方式二:AOF

AOF:以日志的形式来记录每个写操作,将每个redis执行过的所有写指令记录下来(读操作不记录),只许追加文件但不可以改写文件,redis启动之初会读取该文件,完成数据的恢复。默认情况下,redis没有开启AOF(append only file),开启AOF功能需要设置配置:appendonly yes

AOF保存的是appendonly.aof文件

AOF持久化工作流程:命令追加、写入磁盘文件(文件写入和文件同步)

        当服务器执行完一个写命令后,会将该命令以追加的方式写到服务器的aof_buf(aof缓冲区)的末尾,再将aof_buf中的数据写入到磁盘中的aof文件中(需要两步操作:文件写入和文件同步)。

文件写入和文件同步:操作系统为了提高性能,使用了页缓存机制(page cache),在将aof_buf中的数据写入到磁盘中时,并不是一步到位,而是先将aof_buf中的数据写入到page cache中,再由操作系统实现文件同步,将page chahe 中的数据同步到磁盘文件(aof文件)中。

AOF缓冲区三种写回策略:

always:每执行完一个写命令后立刻将该命令写入并同步到磁盘aof文件中

everysec:每秒写回,每个命令执行完,只是先把日志写到aof_buf中,每隔一秒(距离上一次同步间隔一秒)再将aof_buf中的内容写入并同步到磁盘aof文件中。

no:由操作系统控制文件的同步。即每个命令执行完,将日志写到aof缓冲区,再将aof_buf中的内容写入到page cache中,具体什么时候同步到磁盘文件中,由操作系统来决定。

AOF优点

  1. 更好的保护数据不丢失,比RDB更可靠,设置不同的写回策略,默认是always。everysec和no的写回策略,最多也就丢失一秒钟的数据。
  2. 当AOF文件太大时,redis提供了AOF重写机制,减小AOF 文件的大小。

AOF缺点:

  1. 相同数据集,AOF文件一般比RDB文件大。
  2. 根据所使用的写回策略,AOF的速度可能慢于RDB。

AOF重写:

        当AOF文件越来越大,使用AOF 文件来进行数据的还原所需的时间就越来越多,AOF重写就是用来减小AOF文件体积。redis生成新的aof文件代替旧的aof文件。

比如:有如下命令,set k1 1,set k1 2,set k1 3,set k1 4,这样最终的结果是k1 4 ,实际上只需要记录set k1 4就行,没必要记录前三条命令,AOF重写 就是启动AOF 文件内容压缩,只保留可以恢复数据集的最小指令集。

自动触发AOF 重写:

AOF重写默认配置:

auto-aof-rewrite-percentage 100

auto-aof-rewrite-min-size 64mb

同时满足上面两个配置项才会触发AOF重写:①根据上次重写后的AOF文件大小,判断当前AOF文件大小是否增长了一倍②当前AOF文件大小超过64mb

手动触发:

执行命令:bgrewriteaof

AOF重写可能出现的问题及解决方案

1、重写阻塞主进程

解决:使用子进程进行重写,

2、子进程重写的过程中,主进程仍然会有后续的写命令要记录日志,这样会导致最终重写后的新aof文件与旧的出现数据不一致问题。

解决:redis引入了AOF重写缓冲区,此缓冲区在fork出子进程后开始使用,当redis服务器执行完每一个写命令后,他会同时将命令追加到AOF重写缓冲区和AOF缓冲区。这样,当子进程完成重写工作后,通知主进程,主进程会将AOF重写缓冲区的新增的写命令追加到新的AOF文件中,然后用新的AOF文件代替旧的AOF文件就完成了AOF文件的重写。

3、若AOF重写缓冲区内容过多,导致主进程出现阻塞(AOF重写缓冲区的内容是由主进程追加到新AOF文件的)。

解决:在进行 AOF 后台重写时,Redis 会创建一组用于父子进程间通信的管道,同时会新增一个文件事件,该文件事件会将写入 AOF 重写缓冲区的内容通过该管道发送到子进程在子进程重写结束后,子进程会通过该管道尽量从父进程读取更多的数据,每次等待可读取事件1ms,如果一直能读取到数据,则这个过程最多执行1000次,也就是1秒。如果连续20次没有读取到数据,则结束这个过程。


方式三:RDB-AOF混合持久化

结合RDB和AOF 两种持久化方式

结论:RDB做全量持久化,AOF做增量持久化

        先使用RDB进行快照存储,时候使用AOF持久化记录所有写操作,当重写策略满足或是手动触发重写时,将最新的数据存储为新的RDB记录。这样的话,重启服务时会从RDB和AOF两部分恢复数据,既提高了数据完整新,又提高了恢复数据的性能。

整体格式:[RDB file][AOF tail]

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值