Redis持久化(Redis persistence)是指将数据写入持久化存储,如固态硬盘(SSD)
Redis提供了一系列持久化选项,这些包括:
在指定的时间间隔,执行数据集的时间点快照
实现类似照片记录效果的方式,就是把某一时刻的数据和状态以文件的形式写到磁盘上,也就是快照。这样一来即使故障宕机,快照文件也不会丢失,数据的可靠性也就得到了保证。
这个快照文件就称为RDB文件(dump.rdb),其中,RDB就是Redis DataBase的缩写。
在指定的时间间隔内将内存中的数据集快照写入磁盘,也就是行话讲的Snapshot内存快照,它恢复时再将硬盘快照文件直接读回到内存里
Redis的数据都在内存中,保存备份时它执行的是全量快照,也就是说,把内存中的所有数据都记录到磁盘中
在默认情况下,Redis将数据库快照保存在名字dump.rdb的二进制文件中。可以对Redis进行设置,让它在"N秒内数据集至少有M个改动"这一条被满足时,自动保存一次数据集。也可以通过调用SAVE或BGSAVE,手动让Redis进行数据集保存操作
比如说,以下设置会让Redis在满足"60秒内有至少有1000个键被改动"这一条件时,自动保存一次数据集:save 60 1000
redis6.2以及redis7.0
RDB的优点
RDB的缺点
下面配置到了redis安装目录下,当然也可以配置到其他目录下,默认是./
先在redis7.conf配置文件的地方新建一个文件夹,dumpfiles保存于/myredis/dumpfiles
快照文件名默认为dump.rdb,可以对其进行修改
这里在名称中添加当前的端口号,设置为
dump6379.rdb
在redis中支持通过config get或set进行配置文件的更改
设置redis.conf文件中的自动触发时间:save
FLUSHDB和FLUSHALL命令
执行flushdb或者flushall命令也会触发RDB快照,不过里面是空的,以便下次启动redis服务是读取到的就是空文件。
执行shutdown命令之前会将当前的数据进行一次快照保存。
总结:
不可以把备份文件dump.rdb和生成redis服务器放在同一台机器,必须分开各自存储,以防止生产机物理损坏后备份文件也挂了
Redis提供了两个命令来生成RDB文件,分别是save和bgsave
SAVE命令在主程序中执行会阻塞当前进程,直到持久化工作完成,redis才能处理其他命令。工作中禁止使用该命令。
127.0.0.1:6379> set name Alice
OK
127.0.0.1:6379> set age 18
OK
127.0.0.1:6379> save # 立马将数据保存到快照中,如果数据量大会造成阻塞
OK
BGSAVE命令会fork一个子进程在后台异步进行持久化工作,持久化期间redis可以执行其他命令。
在Linux程序中,fork()会产生一个和父进程完全相同的子进程,但子进程在此后多会exec系统调用,出于效率考虑,尽量避免膨胀。
127.0.0.1:6379> set name Cindy
OK
127.0.0.1:6379> set age 20
OK
127.0.0.1:6379> BGSAVE
Background saving started # 在后台执行持久化
LASTSAVE命令可以获取最后一次成功执行快照的时间。得到的是一个时间戳,可以通过date -d @时间戳
命令获取对应的时间。
127.0.0.1:6379> LASTSAVE
(integer) 1681223083
127.0.0.1:6379> quit
[root@redis ~]# date -d @1681223083
2023年 04月 11日 星期二 22:24:43 CST
有些情况下快照保存的数据不完整导致无法读取快照数据,可以使用
redis-check-rdb
命令对rdb文件进行修复。
[root@redis redis-7.0.10]# redis-check-rdb dump.rdb
[offset 0] Checking RDB file dump.rdb
[offset 27] AUX FIELD redis-ver = '7.0.10'
[offset 41] AUX FIELD redis-bits = '64'
[offset 53] AUX FIELD ctime = '1681233313'
[offset 68] AUX FIELD used-mem = '1104992'
[offset 80] AUX FIELD aof-base = '0'
[offset 82] Selecting DB ID 0
[offset 155] Checksum OK
[offset 155] \o/ RDB looks OK! \o/
[info] 8 keys read
[info] 0 expires
[info] 0 already expired
redis在启动服务时会读取配置的快照保存路径中的dump.rdb文件,所以只需要将备份的rdb文件放到配置的保存路径中,然后启动redis服务即可还原快照中的数据。
redis-cli config set save ""
:将save的值设置为空,即禁用了快照功能。
在redis客户端则直接执行config set save ""即可。
最好采用如下的配置禁用
停止写bgSave-错误
默认yes
如果配置成no,表示你不在乎数据不一致或者有其他的手段发现和控制这种不一致,那么在快照写入失败时,也能确保redis继续接受新的写请求
RDB压缩
默认yes
对于存储到磁盘中的快照,可以设置是否进行压缩存储。如果是的话,redis会采用LZF算法进行压缩。
如果你不想消耗CPU来进行压缩的话,可以设置为关闭此功能
默认为yes
在存储快照后,还可以让redis使用CRC64算法来进行数据校验,但是这样做会增加大约10%的性能消耗,如果希望获取到最大的性能提升,可以关闭此功能
rdb-del-sync-files:在没有持久性的情况下删除复制中使用的RDB文件启用。默认情况下no,此选项是禁用的
Append Only File缩写。记录每次对服务器的写操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据。
以日志的形式来记录每个写操作,将Redis执行过的所有写指令记录下来(读操作不记录,只许追加文件但不可用改写文件,redis启动之初会读取该文件重新构建数据,换言之,redis重启的话就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作
AOF优缺点:
优点:
AOF缺点:
①Client作为命令的来源,会有多个源头以及源源不断的请求命令
②在这些命令到达Redis Server以后并不是直接写入AOF文件,会将其这些命令先放入AOF缓存中进行保存。这里的AOF缓冲区实际上是内存中的一片区域,存在的目的是当这些命令达到一定量以后再写入磁盘,避免频繁的磁盘IO操作
③AOF缓冲会根据AOF缓冲区同步文件的三种写回策略将命令写入磁盘上的AOF文件
④随着写入AOF内容的增加为避免文件膨胀,会根据规则进行命令的合并(又称AOF重写),从而起到AOF文件压缩的目的
⑤当Redis Server服务器重启的时候会从AOF文件载入数据
AOF默认是关闭的,需要将配置文件中appendonly设置为yes。而保存机制我们就不改了,使用everysec
AOF保存文件的位置和RDB保存文件的位置一样,都是通过redis.conf配置文件的dir配置
dir + appenddirname
aof文件的保存路径和rdb的保存路径是同一个,只不过AOF会在该路径下创建一个appendonlydir文件夹,然后将aof文件保存在该文件夹下。Redis7的aof文件分为三个文件:
appendonly.aof.1.base.rdb
基本文件:存储aof重写后的数据
appendonly.aof.1.incre.aof
追加文件:存储aof追加的数据,达到一定大小后触发AOF重写。
appendonly.aof.manifest
清单文件:追踪管理aof。
AOF有三种写回策略:
配置项 | 写回时机 | 优点 | 缺点 |
---|---|---|---|
Always | 同步写回 | 可靠性高,数据基本不丢失 | 每个写命令都要同步记录,性能影响较大 |
Everysec | 每秒写回 | 性能适中 | 宕机时丢失一秒内的数据 |
No | 操作系统控制的写回 | 性能好 | 宕机时丢失数据较多 |
在同时开启RDB和AOF持久化时,重启redis服务只会加载aof文件,不会加载rdb文件,即使启动时没有appendonlydir目录,也会创建一个新的appendonlydir目录。
在开启了AOF后,当AOF文件出现异常时,redis服务无法正常启动。可以使用
redis-check-aof --fix 文件名
命令修复文件。
如果误执行了FLUSHALL操作,先停止服务器, 移除 AOF 文件末尾的 FLUSHALL 命令, 并重启 Redis , 就可以将数据集恢复到 FLUSHALL 执行之前的状态。因为FLUSHALL或者FLUSHDB也是写命令,会被追加到aof文件中。
因为 AOF 的运作方式是不断地将命令追加到文件的末尾, 所以随着写入命令的不断增加, AOF 文件的体积也会变得越来越大。
举个例子, 如果对一个计数器调用了 100 次 INCR , 那么仅仅是为了保存这个计数器的当前值, AOF 文件就需要记录100 条记录。然而在实际上, 只使用一条 SET 命令已经足以保存计数器的当前值了, 其余 99 条记录实际上都是多余的。
为了处理这种情况, Redis 可以在不打断服务客户端的情况下, 对 AOF 文件进行重建,即自动执行BGREWRITEAOF
命令, Redis 将生成一个新的 AOF 文件, 这个文件包含重建当前数据集所需的最少命令。Redis 2.2 需要自己手动执行 BGREWRITEAOF 命令; Redis 2.4后则可以自动触发 AOF 重写。
自动触发需要满足配置文件中的设置,官方默认设置是:
auto-aof-rewrite-percentage 100
:根据上次重写后的aof大小,判断当前aof大小是不是增长了1倍。100%表示一倍。
auto-aof-rewrite-min-size 64mb
:重写时满足的文件大小,即incr.aof文件超过了64兆才会重写。注意同时满足这两个条件才会触发。
执行命令
BGREWRITEAOF
即可执行AOF重写。
1.在重写开始前,redis会fork一个“重写子进程”,这个子进程会读取现有的AOF文件,并将其包含的指令进行分析压缩并写入到一个临时文件中。
2.与此同时,主进程会将新接收到的写指令一边累积到内存缓冲区中,一边继续写入到原有的AOF文件中,这样做是保证原有的AOF文件的可用性,避免在重写过程中出现意外。
3.当“重写子进程”完成重写工作后,它会给父进程发一个信号,父进程收到信号后就会将内存中缓存的写指令追加到新AOF文件中。
4.当追加结束后,redis就会用新AOF文件来代替旧AOF文件,之后再有新的写指令,就都会追加到新的AOF文件中。
5.重写aof文件的操作,并没有读取旧的aof文件,而是将整个内存中的数据库内容用命令的方式重写了一个新的aof文件,这点和快照有点类似。
推荐方式:RDB+AOF混合方式:RDB镜像做全量持久化,AOF做增量持久化
结合了RDB和AOF的优点,既能快速加载又能避免丢失过多的数据。
必须首先开启AOF:appendonly yes
,默认是关闭的
开启AOF+RDB混合模式:aof-use-rdb-preamble yes
,默认是开启的。
同时开启AOF和RDB持久化,当Redis重启时会优先加载AOF文件来恢复原始的数据,因为在通常情况下,AOF保存的数据集要比RDB文件保存的数据集要完整。
在持久化时,先使用RDB进行快照存储,然后使用AOF持久化记录所有写的操作,当重写策略满足或者手动触发重写的时候,将最新的数据存储为新的RDB记录。这样的话,重启服务的时候会从RDB和AOF两部分恢复数据,既保证了数据的完整性,又提高了恢复数据的性能,简单来说:混合持久化方式产生的文件一部分是RDB格式,一部分是AOF格式。----》AOF包括了RDB头部+AOF混写
纯缓存模式即同时关闭AOF和RDB,这样可以最大化redis的读写性能,但无法保证数据的安全性。
关闭RDB:修改配置文件save ""
禁用RDB持久化模式,仍然可以使用命令save、bgsave生成rdb文件。
关闭AOF:修改配置文件appendonly no
禁用AOF持久化模式,仍然可以使用命令bgrewriteaof生成aof文件。