在指定的时间间隔内将内存中的数据以快照的形式保存到磁盘
过程:
1 客户端执行bgsave命令,redis主进程收到指令并判断此时是否在执行bgrewriteaof,
如果此时正好在执行则bgsave直接返回,不fork子进程,如果没有执行2bgrewriteaof重写AOF文件,则进入下一个阶段;
3主进程调用fork方法创建子进程,在创建过程中redis主进程阻塞,所以不能响应客户端请求;
4子进程创建完成以后,bgsave命令返回“Background saving started”,此时标志着redis可以响应客户端请求了;
子经常根据主进程的内存副本创建临时快照文件,当快照文件完成以后对原快照文件进行替换;
子进程发送信号给redis主进程完成快照操作,主进程更新统计信息(info Persistence可查看),子进程退出;
触发RDB的时机:
1 在配置文件中配置触发的条件
15min内有一个key变化
5min内有10个key变化
1min内有1w个key变化
具体的时间以及次数可以在配置文件中修改
修改save 秒钟 写操作次数
save 900 1
save 300 10
save 60 10000
RDB相关配置
save m n
#配置快照(rdb)促发规则,格式:save
#save 900 1 900秒内至少有1个key被改变则做一次快照
#save 300 10 300秒内至少有300个key被改变则做一次快照
#save 60 10000 60秒内至少有10000个key被改变则做一次快照
#关闭该规则使用svae “”
dbfilename dump.rdb
#rdb持久化存储数据库文件名,默认为dump.rdb
stop-write-on-bgsave-error yes
#yes代表当使用bgsave命令持久化出错时候停止写RDB快照文件,no表明忽略错误继续写文件。
rdbchecksum yes
#在写入文件和读取文件时是否开启rdb文件检查,检查是否有无损坏,如果在启动是检查发现损坏,则停止启动。
dir "/etc/redis"
#数据文件存放目录,rdb快照文件和aof文件都会存放至该目录,请确保有写权限
rdbcompression yes
#是否开启RDB文件压缩,该功能可以节约磁盘空间、
停止备份:
在配置文件中就设置save “”
或在命令行中 config set save “”
save,会立即生成dump.rdb,但是会阻塞往redis内存中写入数据
bgsave:后台异步备份
如果是使用flushdb命令,会把之前的快照更新成当前的空状态
所以执行了flushdb后更新的快照是没有数据的
恢复RDB文件
将dump.rdb文件移动到redis的工作目录下,重启redis服务
获取工作目录: confi get dir
优点:恢复大量文件时速度快
缺点:存在数据丢失的风险,fock的子线程占用内存
一个日志文件,实时备份客户端对redis的写操作记录,只需添加,不许修改
AOF可以与RDB共存。但是恢复时先加载AOF
开启方式:在配置文件中设置 appendonly true
恢复方式:将aof文件放在redis的工作路径下
异常恢复:先使用redis-check-aof --fix 来删除aof中有语法错误的操作记录
redis的每一条命令以redis协议添加到缓存区aof_buf中,然后根据同步策略一次性写入磁盘
这样可以节省磁盘IO次数
appendfsysnc: 保存操作记录的模式
always: 每次有数据修改时添加记录 性能差
everysecond:每秒记录一次 默认 最多丢失1s的数据
即每秒把缓冲区的数据写入磁盘
no: 由OS决定何何时同步,linux通常是30s
当aof文件内容过多时,需要压缩原有的记录,优化原有的操作记录
执行的操作:
1 重复或者无效的操作记录不写入
2 过期的数据不再写入
3 多条命令合并
只保留可以恢复数据的最小指令集
当前aof文件的大小是上次rewrite后的两倍且大于64M
具体大小配置 :
auto-aof-rewrite-min-size 64mb 生产环境下要配置的比较大
auto-aof-rewrite-percentage: 100 增长的百分比
也可使用命令bgwriteaof
aof_rewrite_buf 代表重写缓冲区 aof_buf代表写操作命令存放的缓冲区
1.开始bgrewriteaof,判断当前有没有bgsave命令(RDB持久化)/bgrewriteaof在执行,倘若有,则这些命令执行完成以后在执行。
2.主进程fork出子进程,在这一个短暂的时间内,redis是阻塞的。
3.主进程fork完子进程继续接受客户端请求,所有写命令依然写入AOF文件缓冲区并根据appendfsync策略同步到磁盘,保证原有AOF文件完整和正确。由于fork的子进程仅仅只共享主进程fork时的内存,因此Redis使用采用重写缓冲区(aof_rewrite_buf)机制保存fork之后的客户端的写请求,防止新AOF文件生成期间丢失这部分数据。此时,客户端的写请求不仅仅写入原来aof_buf缓冲,还写入重写缓冲区(aof_rewrite_buf)。
也就是在进行rewrite时,主进程不仅把客户端的命令写入缓冲区,还会写入重写缓冲区,让子进程读取最新的命令记录。
4.子进程通过内存快照,按照命令重写策略写入到新的AOF文件。
4.1子进程写完新的AOF文件后,向主进程发信号,父进程更新统计信息。
4.2主进程把AOFaof_rewrite_buf中的数据写入到新的AOF文件(避免写文件是数据丢失)。
5.使用新的AOF文件覆盖旧的AOF文件,标志AOF重写完成。
AOF文件内容:
AOF实现本质是基于redis通讯协议,将命令以纯文本的方式写入到文件中。
redis协议:
首先Redis是以行来划分,每行以\r\n行结束。每一行都有一个消息头,消息头共分为5种分别如下:
(+) 表示一个正确的状态信息,具体信息是当前行+后面的字符。
(-) 表示一个错误信息,具体信息是当前行-后面的字符。
(*) 表示消息体总共有多少行,不包括当前行,*后面是具体的行数。
(KaTeX parse error: Can't use function '\r' in math mode at position 21: …一行数据长度,不包括换行符长度\̲r̲\n,后面则是对应的长度的数据。
auto-aof-rewrite-min-size 64mb
#AOF文件最小重写大小,只有当AOF文件大小大于该值时候才可能重写,4.0默认配置64mb。
auto-aof-rewrite-percentage 100
#当前AOF文件大小和最后一次重写后的大小之间的比率等于或者等于指定的增长百分比,如100代表当前AOF文件是上次重写的两倍时候才重写。
appendfsync everysec
#no:不使用fsync方法同步,而是交给操作系统write函数去执行同步操作,在linux操作系统中大约每30秒刷一次缓冲。这种情况下,缓冲区数据同步不可控,并且在大量的写操作下,aof_buf缓冲区会堆积会越来越严重,一旦redis出现故障,数据
#always:表示每次有写操作都调用fsync方法强制内核将数据写入到aof文件。这种情况下由于每次写命令都写到了文件中, 虽然数据比较安全,但是因为每次写操作都会同步到AOF文件中,所以在性能上会有影响,同时由于频繁的IO操作,硬盘的使用寿命会降低。
#everysec:数据将使用调用操作系统write写入文件,并使用fsync每秒一次从内核刷新到磁盘。 这是折中的方案,兼顾性能和数据安全,所以redis默认推荐使用该配置。
aof-load-truncated yes
#当redis突然运行崩溃时,会出现aof文件被截断的情况,Redis可以在发生这种情况时退出并加载错误,以下选项控制此行为。
#如果aof-load-truncated设置为yes,则加载截断的AOF文件,Redis服务器启动发出日志以通知用户该事件。
#如果该选项设置为no,则服务将中止并显示错误并停止启动。当该选项设置为no时,用户需要在重启之前使用“redis-check-aof”实用程序修复AOF文件在进行启动。
appendonly no
#yes开启AOF,no关闭AOF
appendfilename appendonly.aof
#指定AOF文件名,4.0无法通过config set 设置,只能通过修改配置文件设置。
dir /etc/redis
#RDB文件和AOF文件存放目录
优势:可以保证数据的一致性。因为它可以实时或者每秒记录客户端对redis的操作
缺点:aof文件比rdb文件大,恢复速度慢
redis先加载AOF文件来恢复原始数据,因为AOF数据比rdb更完整
但是aof存在潜在的bug,如把错误的操作记录写入了aof,会导出数据恢复失败
所以可以把RDB作为后备数据
为了考虑性能,可以只在Slave上开启RDB,并且15min备份一次 ,
如果为了避免AOF rewite的IO以及阻塞,可以在Redis集群中不开启AOF,
靠集群的备份机制来保证可用性,在启动时选取较新的RDB文件
如果集群全部崩溃,会丢失15min前的数据
redis4.0开始支持该模式
为了解决的问题:
redis在重启时通常是加载AOF文件,但加载速度忙
因为RDB数据不完整,所以加载AOF
开启方式: aof-use-rdb-preamble true
开启后,AOF在重写时会直接读取RDB中的内容
运行过程:
通过bgrwriteaof完成,不同的是当开启混合持久化后,
1 子进程会把内存中的数据以RDB的方式写入aof中,
2 把重写缓冲区中的增量命令以AOF方式写入到文件
3 将含有RDB个数和AOF格数的AOF数据覆盖旧的AOF文件
新的AOF文件中,一部分数据来自RDB文件,一部分来自Redis运行过程时的增量数据
当我们开启了混合持久化时,启动redis依然优先加载aof文件,aof文件加载可能有两种情况如下:
aof文件开头是rdb的格式, 先加载 rdb内容再加载剩余的 aof。
aof文件开头不是rdb的格式,直接以aof格式加载整个文件。
优点:既能快速备份又能避免大量数据丢失
缺点:RDB是压缩格式,AOF在读取它时可读性教差
优点:
RDB 是一个非常紧凑(compact)的文件,体积小,因此在传输速度上比较快,因此适合灾难恢复。
RDB 可以最大化 Redis 的性能:父进程在保存 RDB 文件时唯一要做的就是 fork 出一个子进程,然后这个子进程就会处理接下来的所有保存工作,父进程无须执行任何磁盘 I/O 操作。
RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快。
缺点:
RDB是一个快照过程,无法完整的保存所以数据,尤其在数据量比较大时候,一旦出现故障丢失的数据将更多。
当redis中数据集比较大时候,RDB由于RDB方式需要对数据进行完成拷贝并生成快照文件,fork的子进程会耗CPU,并且数据越大,RDB快照生成会越耗时。
RDB文件是特定的格式,阅读性差,由于格式固定,可能存在不兼容情况。
优点:
数据更完整,秒级数据丢失(取决于设置fsync策略)。
兼容性较高,由于是基于redis通讯协议而形成的命令追加方式,无论何种版本的redis都兼容,再者aof文件是明文的,可阅读性较好。
缺点:
数据文件体积较大,即使有重写机制,但是在相同的数据集情况下,AOF文件通常比RDB文件大。
相对RDB方式,AOF速度慢于RDB,并且在数据量大时候,恢复速度AOF速度也是慢于RDB。
由于频繁地将命令同步到文件中,AOF持久化对性能的影响相对RDB较大,但是对于我们来说是可以接受的。
混合持久化
优点:
混合持久化结合了RDB持久化 和 AOF 持久化的优点, 由于绝大部分都是RDB格式,加载速度快,同时结合AOF,增量的数据以AOF方式保存了,数据更少的丢失。
缺点:
兼容性差,一旦开启了混合持久化,在4.0之前版本都不识别该aof文件,同时由于前部分是RDB格式,阅读性较差