Redis持久化机制

redis支持RDB和AOF两种持久化机制,持久化功能有限地避免进程退出造成的数据丢失问题,当下次重启时利用之前持久化的文件即可是事先数据恢复。

1 RDB

  RDB持久化是按照事先定制的策略,周期性的从内存中读取出来保存至硬盘,数据文件默认为dump.rdb;触发RDB持久化过程分为手动触发和自动触发;

1.1 触发机制

1)手动触发分别对应SAVE和BGSAVE命令;

  • SAVE命令:同步,在主线程中保存快照;此时会堵塞所有客户端请求;对于内存比较大的实例会造成长时间堵塞,线上环境不建议使用;

  • BGSAVE命令:异步,Redis进程执行fork操作创建子进程,RDB持久化过程由子进程负责,完成后自动结束。堵塞只发生在fork阶段,一般时间很短;

显然BGSAVE命令是针对SAVE堵塞问题做的优化。因此Redis内部所有的设计RDB的操作都采用BGSAVE的方式,而save命令已经废弃。

2)自动触发RDB的持久化机制,例如一下场景;

  1. 使用save相关配置,如“save m n”。表示m秒内数据采集存在n次修改时,自动触发bgsave。
  2. 如果从节点执行全量复制操作,主节点自动执行BGSAVE生成RDB文件并发送给从节点。
  3. 执行debug reload命令重新加载Redis时,也会自动触发save操作。
  4. 默认情况下执行shutdown命令时,如果没有开启AOF持久化功能则自动执行BGSAVE。

1.2 RDB相关配置

  SAVE 900 1     #900秒内如果超过1个key被修改,则发起快照保存
  SAVE 300 10    #300秒内容如超过10个key被修改,则发起快照保存
  SAVE 60 10000 #60秒内容如果超过10000个key被修改,则发起快照保存
  SAVE ""    #关闭RDB功能
  stop-writes-on-bgsave-error yes  #在进行快照备份时,一旦监控到持久化发生错误,是否停止操作   rdbcompression yes        #RDB文件是否执行压缩来节约空间   rdbchecksum yes         #是否对RDB的镜像文件做校验码进行检测   dbfilename dump.rdb        #指明快照文件名字   dir /data/redis/         #指明文件报错目录

1.3 流程说明

  1)Redis调用系统函数fork(),创建一个子进程,fork操作过程中父进程会阻塞。

  2)父进程继续处理各客户端发出的请求,当子进程将快照写入到临时RDB文件完成时。

  3)Redis会用心的临时RDB文件替换原来的RDB文件,并删除旧RDB文件。

1.5 RDB的优缺点

RDB的优点:

  • RDB是一个紧凑压缩的二进制文件,代表Redis在某个时间点上的数据快照。非常适用于备份,全量复制等场景。比如每6小时执行BGSAVE备份,并把RDB文件拷贝到远程机器或者文件系统中(如HDFS),用于灾难恢复。
  • Redis加载RDB恢复数据远远快于AOF的方式。

RDB的缺点:

  • RDB方式数据没办法做到持久化/秒级持久化。因为BGSAVE每次运行都要执行fork操作创建子进程,属于重量级操作,平凡执行成本过高。
  • RDB文件使用特定二进制格式保存,Redis版本演进过程中有多个格式的RDB版本,存在老版本Redis服务无法兼容新版RDB格式的问题。

针对RDB不适合实时持久化的问题,Redis提供了AOF持久化方式来解决。

2 AOF

  AOF持久化是把每一个命令的操作模式都记录下来,通过记录每一次写操作至指定的文件尾部实现持久化机制,当Redis重启时,可通过重新执行文件中的命令在内存中重建数据库,

2.1 使用AOF

  开启AOF功能需要设置配置:appendonly yes,默认不开启。AOF文件名通过appendfilename配置设置,默认文件名是appendonly.aof。AOF的工作流程操作:命令写入(append)、文件同步(sync)、文件重新(rewrite)、重启加载(load)

2.2 AOF相关配置

appendonly yes  #开启AOF功能
appendfilename "appendonly.aof"   #启用的文件名字
appendfsync {always | everysec | no} {每次收到写命令就立即写入磁盘中的AOF文件|每秒钟写一次|自行不会触发写操作,由操作系统决定什么时候写}
no-appendfsync-on-rewrite no    #对新写的操作放在缓存队列中
auto-aof-rewrite-percentage 100  #当前的AOF文件已经是上次重写的二倍时,再重新触发一次重写操作
auto-aof-rewrite-min-size 64mb   #启动新的日志重启重写过程中的最小值

2.3 重写机制

  随着命令不断写入AOF,文件会越来越大,为了解决这个问题,Redis引入AOF重写机制压缩文件体积。AOF文件重写是把Redis进程内的数据转换为写命令同步到新的AOF文件的过程。

 AOF重写过程可以手动触发和自动触发:

  • 手动触发:直接调用 BGREWRITEAOF命令。
  • 自动触发:根据auto-aof-rewrite-min-size 和 auto-aof-rewrite-percentage参数确定自动触发时机.
    • auto-aof-rewrite-min-size :表示AOF重写时文件最小值,默认为64MB
    • auto-aof-rewrite-percentage:当前AOF文件已经是上次重写的二倍时,再重新触发一次重写操作

2.4 流程说明

  1)Redis主进程通过fork创建子进程;
  2)子进程根据Redis内存中的数据穿件数据库重建命令序列临时文件中
  3)父进程继续接受客户端请求,并会把这些请求中的写操作继续追加至原来的AOF文件,额外的,这些新的写请求还会放置一个缓存队列中
  4)子进程重写完成,会通知父进程,父进程把缓冲中的命令写到临时文件中
  5)父进程用临时文件替换老的aof文件不会读取正在使用AOF文件,而通过将内存中的数据以命令的方式保存在临时文件中,完成之后替换原来的AOF文件

2.5 文件校验

  加载损坏的AOF文件时会拒绝启动,并打印日志:

    # Bad file format reading the append only file: make a backup of your AOF file, then use ./redis-check-aof --fix <filename>

  运维提示:
    对于错误格式的AOF文件,先进行备份,然后采用redis-check-aof--fix命令进行修复,修复后使用diff-u对比数据的差异,找出丢失的数据,有些可以人工修改补全

  AOF文件可能存在结尾不完整的情况,比如机器突然掉电导致AOF尾部文件命令写入不全。Redis为我们提供了aof-load-truncated配置来兼容这种情况,默认开启。加载AOF时,当遇到此问题时会忽略并继续启动,同时打印如下警告日志:
    # !!! Warning: short read while loading the AOF file !!!
    # !!! Truncating the AOF at offset 397856725 !!!
    # AOF loaded anyway because aof-load-truncated is enabled

原文地址:https://www.cnblogs.com/Gnnnny/p/10363323.html