Redis在运行中,数据是存储在内存中的,因为存在各种问题导致服务器宕机或者进程死掉,那么重新启动Redis之后数据就没有了,所以我们需要一种持久化机制,将内存中的数据持久化到磁盘,下一次重启就可以从持久化文件恢复数据。Redis提供了2种持久化机制:RDB和AOF
一 RDB
RDB持久化就是Redis 把当前进程的数据生成快照存储到磁盘的过程,持久化的触发过程中分为:自动触发和手动触发。
1.1 自动触发
save m n
自动触发可以通过配置设置多少秒内存在多少次修改的时候,自动触发。比如配置文件中设置 save 900 10,表示900秒内存在10次修改就开始自动触发持久化。
1.2 手动触发
手动触发,顾名思义就是通过人为手段使用命令进行持久化。手动触发可以使用save和bgsave。
1.2.1 save
阻塞当前Redis服务器,直到RDB持久化完成,这个肯定在线上是不能用的
1.2.2 bgsave
Redis进程fork一个子进程,然后子进程负责持久化 ,这里也有可能有阻塞,就是创建子进程的时候,但是这个代价比save要小很多。
1.3 RDB文件处理
RDB文件保存在dir目录下,文件名字可以通过dbfilename指定。Redis默认会对rdb文件进行压缩处理,压缩后的文件远远小于内存大小默认开启压缩,即rdbcompression yes,若果不开启就配置off
这个参数虽然开启会消耗CPU,但是会大幅度降低rdb文件体积,方便保存和发送到其他网络。
如果Redis加载损坏的RDB文件的时候拒绝启动,可以使用Redis提供的redis-check-dump工具检测RDB文件并获取对应的错误报告
二 AOF
AOF 默认是不开启的,需需要在在配置文件配置appendonly yes。 Aof文件名字是appendonly.aof,保存路径也在dir指定的目录之下。
2.1 AOF 工作流程
第一:所有写入的命令会追加到缓冲区(aof_buf)
第二: AOF缓冲区根据对应的策略向硬盘做同步操作,将命令以文本格式写入。
第三: 随着AOF文件越拉越大,需要定期对AOF文件进行重写,达到压缩目的
第四:当Redis实例重启的时候,加载AOF文件进行数据恢复
2.2 AOF 重写工作流程
#1 Redis执行AOF重写请求
#2 Redis进程阻塞,fork一个子进程
#3 Redis创建完毕子进程继续处理命令,写入AOF缓存
#4 Redis并且同时将处理的命令写入AOF重写缓存
#5 Redis子进程创建新的AOF文件,并且根据fork之后的数据副本进行AOF重写
#6 Redis子进程将AOF文件重写完成之后,通知父进程
#7 Redis父进程把AOF重写缓冲区数据写入新AOF文件
#8 Redis父进程使用新的AOF文件替换旧的
2.3 文件同步策略
always: 每一次写入都要同步文件,在SATA硬盘上,Redis支持大于几百TPS写入
no: 不做同步
everysec: 建议的同步策略,每一秒同步一次
2.4 重写机制
随着命令不断写入,文件越拉越大,引入重写机制解决这个问题,压缩文件体积。这时候会把文件内的数据写的命令同步到新AOF:
#1 超时的数据不再写入
#2 旧文件无效的命令,比如del hdel srem set a 1 set a 2等
#3 多条命令合并为一个
2.4.1 自动触发
auto-aof-rewrite-min-size和auto-aof-rewrite-percentage参数确定自动触发时间。
auto-aof-rewrite-min-size:默认64M,即要自动触发AOF文件必须当前文件要大于64M
aof_rewrite_base_size:最近一次重写的大小
auto-aof-rewrite-percentage: 当AOF日志超过基准大小(aof_rewrite_base_size)的特定百分比时
2.4.2 手动触发
直接调用bgrewriteof命令就可以触发
三 Redis重启加载文件流程
#1 如果开启AOF,则判断是否有AOF文件
#2 如果AOF文件存在,则加载AOF文件
#3 如果AOF没有可以活着开启了但是没有AOF文件,检查是否有RDB文件
#4 如果RDB文件不存在则启动成功,不需要加载任何文件
#5 如果RDB文件存在则加载RDB文件
四 RDB和AOF比较
4.1 相同点
#1 都是为了持久化redis进程中的数据,下一次重启的时候可以加载持久化文件进行读取
#2 都会fork一个子进程来处理
4.2 不同点
#1 备份方式不同:RDB是全量备份,每一次备份都代表某一个时间点的数据快照;AOF是增量备份,可能是修改一次数据库或者每一秒就备份一次
#2 文件格式不一样:RDB是压缩的二进制格式,体积较小;AOF是文本格式,体积相对较大
#3 数据恢复速度不同:RDB因为是压缩的二进制格式,所以恢复速度比较快;AOF是文本格式,所以恢复速度慢
#4 备份精度不一样: RDB无法做到实时持久化或者按秒持久化,因为本身RDB就属于全量备份,不适合频繁执行;AOF可以做到实时持久化或者按秒持久化
五 怎么选择哪一种持久化方式
如果你可以忍受数分钟数据丢失,那就可以只使用rdb; 如果不允许的话推荐两种都使用,rdb用于容灾备份,便于传输,而且数据恢复速度快。其他情况就可以使用aof 恢复数据。所以不建议单独使用aof或者rdb。
重启 Redis 时,我们很少使用 rdb 来恢复内存状态,因为会丢失大量数据。我们通常使用 aof 日志重放,但是重放 aof 日志性能相对 rdb 来说要慢很多,这样在 Redis 实例很大的情况下,启动需要花费很长的时间。
Redis 4.X带来了一个新的方式——混合持久化。将 rdb 文件的内容和增量的 aof 日志文件存在一起。这里的 aof 日志不再是全量的日志,而是自持久化开始到持久化结束的这段时间发生的增量 aof 日志,通常这部分 aof 日志很小。