Redis持久化
- RDB:在指定的时间间隔能对你的数据进行快照存储。
- AOF:记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据。
rdb配置
-
save 900 1
表示900s内有1条是写入,就触发产生一次快照,可以理解为就进行一次备份。 -
save 300 10
表示300s内有10条写入
aof配置
- always:把每个写命令都立即同步到aof,很慢,但是很安全
- everysec:每秒同步一次,出问题会丢失一秒的数据(实际生产使用这个)
- no:redis不处理交给OS来处理,非常快,但是也最不安全
rdb的触发机制
手动触发:
save:会阻塞Redis服务器进程,服务器进程在RDB文件创建完成之前是不能处理任何的命令请求。- bgsave:该触发方式会fork一个子进程,由子进程负责持久化过程,
fork
操作会阻塞,导致Redis读写性能下降。
自动触发:
- 配置文件设置
save <seconds> <changes>
规则,自动间隔性执行bgsave
命令 - 主从复制时,从库全量复制同步主库数据,主库会执行
bgsave
- 执行
flushall
命令清空服务器数据 - 执行
shutdown
时,如果没有开启aof,也会触发执行save
命令。
aof的原理
命令的实时写入 + aof文件的重写(为了减小文件的大小)
实时写入的步骤
-
命令追加(append)
-
文件写入(write)
-
文件同步(sync)
服务器每执行一个写命令,都会把该命令以协议格式先追加到aof_buf
缓存区的末尾,而不是直接写入文件,
避免每次有命令都直接写入硬盘,减少硬盘IO次数。
何时把aof_buf
缓冲区的内容写入保存在AOF文件中,Redis提供了多种策略
-
appendfsync always
: 将aof_buf
缓冲区的所有内容写入并同步到AOF文件,每个写命令同步写入磁盘 -
appendfsync everysec
:将aof_buf
缓存区的内容写入AOF文件,每秒同步一次,该操作由一个线程专门负责 -
appendfsync no
: 将aof_buf
缓存区的内容写入AOF文件,什么时候同步由操作系统来决定
aof重写的触发机制
手动触发: bgrewriteaof
自动触发:根据配置文件规则来触发
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
表示当AOF文件的体积大于64MB,且AOF文件的体积比上一次重写后的体积大了一倍(100%)时,会执行`bgrewriteaof`命令
AOF文件重写并不需要对现有的AOF文件进行任何读取、分享和写入操作,而是通过读取服务器当前的数据库状态来实现的
- 重写会有大量的写入操作,所以服务器进程会
fork
一个子进程来创建一个新的AOF文件 - 在重写期间,服务器进程继续处理命令请求,如果有写入的命令,追加到
aof_buf
的同时,还会追加到aof_rewrite_buf
AOF重写缓冲区 - 当子进程完成重写之后,会给父进程一个信号,然后父进程会把AOF重写缓冲区的内容写进新的AOF临时文件中,再对新的AOF文件改名完成替换,这样可以保证新的AOF文件与当前数据库数据的一致性
数据恢复
Redis4.0开始支持RDB和AOF的混合持久化(可以通过配置项 aof-use-rdb-preamble
开启)
- 如果是redis进程挂掉,那么重启redis进程即可,直接基于AOF日志文件恢复数据
- 如果是redis进程所在机器挂掉,那么重启机器后,尝试重启redis进程,尝试直接基于AOF日志文件进行数据恢复,如果AOF文件破损,那么用
redis-check-aof fix
命令修复 - 如果没有AOF文件,会去加载RDB文件
- 如果redis当前最新的AOF和RDB文件出现了丢失/损坏,那么可以尝试基于该机器上当前的某个最新的RDB数据副本进行数据恢复
同时开启两种持久化方式
在这种情况下,当 redis重启的时候,会优先载入aof文件恢复原始数据。
因为在通常情况下AOF文件保存的数据集要比RDB文件保存的数据集完整。
RDB文件的完整性没有AOF高,同时使用两者时,服务器重启也只会使用AOF文件。
那要不要只使用AOF呢?
建议不要,因为RDB更适合用于备份数据库(AOF在不断变化不好备份),是二进制存储恢复快,而且不会有AOF可能潜在的Bug,留着作为一个万一的手段。
RDB vs AOF
上面介绍了RDB持久化和AOF持久化,那么来看一下他们各自的优缺点以及该如何选择持久化方案
RDB和AOF优缺点
关于RDB和AOF的优缺点,官网上面也给了比较详细的说明redis.io/topics/pers…
RDB
优点:
- RDB快照是一个压缩过的非常紧凑的文件,保存着某个时间点的数据集,适合做数据的备份,灾难恢复
- 可以最大化Redis的性能,在保存RDB文件,服务器进程只需fork一个子进程来完成RDB文件的创建,父进程不需要做IO操作
- 与AOF相比,恢复大数据集的时候会更快
缺点:
- RDB的数据安全性是不如AOF的,保存整个数据集的过程是比繁重的,根据配置可能要几分钟才快照一次,如果服务器宕机,那么就可能丢失几分钟的数据
- Redis数据集较大时,fork的子进程要完成快照会比较耗CPU、耗时
AOF
优点:
- 数据更完整,安全性更高,秒级数据丢失(取决fsync策略,如果是everysec,最多丢失1秒的数据)
- AOF文件是一个只进行追加的日志文件,且写入操作是以Redis协议的格式保存的,内容是可读的,适合误删紧急恢复
缺点:
- 对于相同的数据集,AOF文件的体积要大于RDB文件,数据恢复也会比较慢
- 根据所使用的 fsync 策略,AOF 的速度可能会慢于 RDB。 不过在一般情况下, 每秒 fsync 的性能依然非常高
开启混合持久化
4.0版本的混合持久化默认关闭的,通过aof-use-rdb-preamble
配置参数控制,yes则表示开启,no表示禁用,5.0之后默认开启。
混合持久化是通过bgrewriteaof完成的,不同的是当开启混合持久化时,fork出的子进程先将共享的内存副本全量的以RDB方式写入aof文件,然后在将重写缓冲区的增量命令以AOF方式写入到文件,写入完成后通知主进程更新统计信息,并将新的含有RDB格式和AOF格式的AOF文件替换旧的的AOF文件。简单的说:新的AOF文件前半段是RDB格式的全量数据后半段是AOF格式的增量数据,
混合持久化优缺点
优点:混合持久化结合了RDB持久化 和 AOF 持久化的优点, 由于绝大部分都是RDB格式,加载速度快,同时结合AOF,增量的数据以AOF方式保存了,数据更少的丢失。
缺点:兼容性差,一旦开启了混合持久化,在4.0之前版本都不识别该aof文件,同时由于前部分是RDB格式,阅读性较差。