对于一个企业来说,redis的持久化是不可或缺的,持久化可以使数据恢复;
就比如下面的场景,当redis突然挂了,有可能停电了,也有可能被某个运维人员不小心把机器关了,这时候,当你重启了redis的时候也无法对外提供服务,当大量的请求过来,redis无法命中,在redis里根本找不到数据,这个时候大量的请求就很可能会去到数据库中,从数据库里获取,造成缓存雪崩,这时候很可能数据库就弄挂了;
1 RDB
RDB(Redis Database)是 Redis 默认的持久化方案。定期的会将Redis中的数据进行换成,写入到磁盘中。即在指定目录下生成一个dump.rdb文件。Redis 重启会通过加载dump.rdb文件恢复数据。
1.1 配置
在redis.config配置文件里可以配置自动触发,配置方式如下
################################ SNAPSHOTTING ################################
#
# Save the DB on disk:
#
# save <seconds> <changes>
#
# Will save the DB if both the given number of seconds and the given
# number of write operations against the DB occurred.
#
# In the example below the behaviour will be to save:
# after 900 sec (15 min) if at least 1 key changed
# after 300 sec (5 min) if at least 10 keys changed
# after 60 sec if at least 10000 keys changed
#
# Note: you can disable saving completely by commenting out all "save" lines.
#
# It is also possible to remove all the previously configured save
# points by adding a save directive with a single empty string argument
# like in the following example:
#
# save ""
save 900 1
save 300 10
save 60 10000
这个规则指的是在seconds秒内发生changes次写操作,就会自动进行一次bgsave,生成一个新的dump.rdb文件,这里可以配置多个save,就是多个snapshotting检查点,每到一个检查点,就会check一下。
1.2 RDB的执行流程
(1) redis根据配置文件,尝试去生成一个rdb快照文件。
(2) fork一个子进程出来。
(3) 子进程尝试将数据备份到rdb快照文件中。
(4) 完成rdb快照文件的生成后,就替换之前旧的快照文件。
1.3 RDB的优缺点
RDB的优点
(1) 适合大规模的数据恢复,Redis加载RDB文件的速度比AOF快很多,因为RDB文件中直接存储的是内存数据,而AOF文件中存储的是一条条命令。
(2) 如果对数据完整性和一致性要求不是很高,RDB是很好的选择。
RDB的缺点
(1) 如果业务场景不希望有大数据量的数据丢失,那么RDB没有AOF好。
(2) 如果RDB每次在fork一个子进程去执行RDB快照数据文件生成的时候,如果数据量很大,可能会导致对客户端提供的服务暂停数毫秒,甚至数秒,因此一般不要让RDB间隔太长时间去备份一次。
2 AOF
AOF(append only file),以日志的方式记录每次写命令,服务重启的时候重新执行AOF文件中的命令来恢复内存数据。因为解决了数据持久化实时性的问题,所以目前AOF是Redis持久化的主流方式。
2.1 配置
AOF默认是关闭的,可以在redis.conf配置文件中添加下面配置开启AOF
appendonly yes
2.2 AOF的执行流程
(1) 首先所有的写命令都会追加到缓冲区中。
(2) 然后使用不同的策略将AOF缓冲区中的命令写到AOF文件中。
(3) 随着AOF文件的越来越大,会对AOF文件进行重写。
(4) 当服务器重启的时候,会加载AOF文件并执行AOF文件中的命令用于恢复数据
2.3 AOF持久化的三种策略
Always:服务器每写入一条命令,就调用一次fsync,将缓冲区里面的命令写入到磁盘里面,在这种模式下,性能非常差,吞吐量很低。
Everysec:服务器每一秒重调用一次fsync,将缓冲区里面的命令写入到磁盘里面,AOF默认使用这种策略。
NO:服务器不主动调用fsync,由操作系统决定将缓冲区里面的命令写入磁盘里面,因此这种策略是不可控的。
2.4 AOF重写
redis中存储的数据是有限的,因此很多的数据会过期,或者是被用户删除掉,也可能是被redis的清除算法清理掉,所以可能很多之前已经被清理掉的数据,对应的写日志还停留在AOF中,AOF文件就一个,因此会不断变大,因此AOF会自动在后台每隔一段时间做rewrite操作,就比如AOF日志中已经存放了100W的数据,但是redis中仅仅只有10W数据;基于内存当前的10W条数据,AOF会构建出一套最新的日志,覆盖之前旧的日志;
执行流程:
(1) redis fork一个子进程。
(2) 子进程基于当前内存中的数据,构建日志,开始往一个新的临时的AOF文件中写入日志。
(3) redis主进程,接收到client新的写操作后,在内存中写入日志,同时新的日志也继续写入到旧的AOF文件中。
(4) 子进程写完新的日志文件之后,redis主进程将内存中的新日志再次追加到新的AOF文件中。
(5) 用新的日志文件替换旧的日志文件。
2.5 AOF的优缺点
AOF的优点
(1) AOF可以尽可能的做到让数据不丢失,一般AOF会每隔1秒,通过一个后台线程执行一次fsync操作,因此最多丢失1秒钟的数据。
(2) AOF以append only方式写入,所以没有任何寻址的开销,写入效率很高,而且文件不容易损坏。
(3) AOF的日志可读性非常强。
AOF的缺点
(1) 对同一份数据来说AOF日志文件比RDB数据快照文件更大。
(2) 性能没有RDB高。
2.6 AOF破损文件修复
如果redis在append数据到AOF文件时,机器宕机了,可能会导致AOF文件破损,此时可以用redis-check-aof --fix命令来修复破损的AOF文件;