redis知识之持久化
持久化选项
Redis提供了两种不同的持久化方法来将数据存储到硬盘种。一种方法叫做快照(snapshotting),它可以将存在与某一个时刻的所有数据都写入硬盘当中。另一种方法叫只追加文件(append-only file),即AOF,它会在执行写命令的时候,将被执行的写命令复制到硬盘里面。
将内存中的数据存储到硬盘的一个主要原因是为了之后重用数据,或者为了防止系统故障而将数据备份到一个远程位置。
一、快照持久化
Redis可通过创建快照来获得存储在内存里面数据在某个时间点上的副本。用户还可对快照进行备份,将快照复制到其他服务器从而创建具有相同数据的服务器副本,还可以将快照用与重启服务器之后恢复数据。如果在新的快照文件创建完毕之前,Redis、系统、或者硬件这三者任意一个崩溃了,那么Redis将丢失最近一次创建快照之后写入的所有数据。
举例理解:当前硬盘中保存的快照是下午2点35开始创建的,并且创建成功。下午3点06时,又开始创建新的快照,并且在3:08快照创建完毕之前,有35键进行了更新。如果在3:06和3:08之间系统崩溃导致无法成功创建快照。那么Redis将丢失2点35之后写入的所有数据。
redis.conf中与快照持久化的相关配置
#
save 60 1000
#
stop-writes-on-bgsave-error yes
#
rdbcompression yes
#
rdbchecksum
#
dbfilename snapshot.rdb
#
dir
创建快照的方法:
-
向redis发送BGSAVE命令。此时Redis会fork一个子进程负责将快照写入硬盘,而父进程继续接收处理命令请求
-
向redis发送SAVE命令。Redis服务器在创建完毕之前不再响应任何其他的命令
-
当用户在redis.conf中配置了save选项。如 save 60 10000,表示从redis最近一次创建快照之后计算。当“60秒内有10000次写入”条件满足时,redis自动触发BGSAVE命令。当用户配置多个save选项,则任意一个满足就会触发BGSAVE
-
当redis通过SHUTDOWN命令接收到关闭服务器的请求时,或者接收到标准TERM信号时,会执行一个SAVE命令,阻塞所有客户端,不再执行客户端发送的任何命令,并在SAVE命令执行完成之后关闭服务器
-
当一个redis服务器连接另一个redis服务器,并向对方发送SYNC命令开始一次复制操作的时候,如果主服务器目前没有在执行BGSAVE操作,那么主服务器会执行BGSAVE
由于如果系统真的发生崩溃,用户将丢失最近一次生产快照之后更改的所有数据,因此快照持久化只适用于那些即使丢失一部分数据也不会造成问题的应用,而不能接受这种数据损失的程序。
二、AOF持久化
AOF持久化将被执行的写命令写到AOF文件末尾,以此来记录数据发生的变化。因此redis只要从头到尾重新执行一次AOF文件包含的所有写命令,就可有恢复AOF文件所记录的数据集。
redis.conf中与快照持久化的相关配置
#
appendonly no
#
appendfilename "appendonly.aof"
#
appendfsync everysec
#
no-appendfsync-on-rewrite no
#
auto-aof-rewrite-percentage 100
#
auto-aof-rewrite-min-size 64mb
#
aof-load-truncated yes
#
aof-use-rdb-preamble yes
其中appendfsync选项为同步策略,有三个可选项
- always
每个redis写命令都要同步写入硬盘(严重降低redis速度) - everysec(默认选项,也为推荐选项)
每秒执行一次同步,显示将多个写命令同步到硬盘 - no
让操作系统来决定何时进行同步
三、 AOF 重写
Redis在长久的运行过程中,AOF日志会越来越长,如果实例宕机重启,对整个AOF文件进行重新执行回放会非常的耗时,导致无法处理外来请求。所以需要对AOF日志进行瘦身--AOF重写
redis提供了bgrewriteaof指令对AOF日志进行重写,原理比较简单,就是开辟一个子进程对内存中的数据及逆行遍历转换位一系列的redis操作指令,然后序列化到一个新的AOF日志文件中,紧接着将期间发生的增量AOF日志追加到新的AOF日志文件中,然后替换旧的AOF日志。
通过一段测试来加深为啥AOF重写能够进行瘦身:
执行以下命令
127.0.0.1:6379> sadd setKey vakue1
(integer) 1
127.0.0.1:6379> sadd setKey vakue2
(integer) 1
127.0.0.1:6379> sadd setKey vakue3
(integer) 1
127.0.0.1:6379> sadd setKey vakue4
(integer) 1
127.0.0.1:6379>
再看AOF文件
QQ图片20200726122051.png
接下来执行AOF重写
127.0.0.1:6379> BGREWRITEAOF
Background append only file rewriting started
127.0.0.1:6379>
再来看AOF文件
QQ图片20200726122344.png
从行数直观的可以看到明显指令数缩小了很多
四、redis 混合持久化
重启redis时,很少直接采用rdb恢复内存状态,因为这会丢失大量数据。但是如果通过AOF日志重放,性能相比rdb又慢很多,redis4.0之后为了解决此问题,将RDB和AOF结合:先加载RDB内容,然后再重放期间的AOF增量日志。