Redis作为一个基于内存操作的数据库,相较于磁盘操作,拥有更快的读写速度,但是缺点也很明显:不能持久化数据,这就意味着如果Redis服务器运行重启操作,那么所有存储在内存中的数据将面临丢失的风险。
为了解决数据持久化问题,Redis提供了AOF日志和RDB快照两种方案,两种方案各有所长,可以配合使用,确保数据的稳定性。
必须使用数据持久化吗?
Redis的数据持久化机制是可以关闭的。如果你只是把Redis作为缓存服务使用,Redis中存储的数据仅仅是用来备份的,那么可以关闭Redis的数据持久化机制。但通常来说,仍然建议至少开启RDB快照方式的数据持久化,因为:
-
RDB方式的持久化几乎不损耗Redis本身的性能,在进行RDB持久化时,Redis主进程唯一需要做的事情就是fork出一个子进程,所有持久化工作都是由子进程去完成的。
-
Redis无论因为什么原因crash掉之后,重启时都会自动恢复到上一次RDB快照中记录的数据,这省去了手动从其它数据源(如DB)同步数据的过程,而且要比其它任何的数据回复方式都要快。
-
现在硬盘那么大,真的不缺那一点地方。
RDB快照(Redis DataBase)
为了保证服务的高性能,Redis采用了写时复制的多进程机制来实现RDB快照。具体实现流程如下:
当需要进行RDB快照时,Redis主进程会fork一个子进程出来,子进程共享主进程执行fork时的内存数据,将数据进行遍历,并持久化到磁盘中。
在此期间,主进程可以如往常一样,正常处理客户端的请求,不会出现阻塞情况。
我们可以通过修改redis.conf文件,来配置Redis保存快照的时机:
save [seconds] [changes]
意为在[seconds]秒内,如果发生了[changes]次的数据修改,则进行一次RDB快照保存。Redis默认的RDB策略如下:
save 900 1
# 900秒内,如果发生了1次的数据变更,则进行RDB快照保存
save 300 10
# 300秒内,如果发生了10次的数据变更,则进行RDB快照保存
save 60 1000
# 60秒内,如果发生了至少1000次的数据变更,则进行RDB快照保存
也可以通过 gbsave命令手动触发RDB快照保存
RDB的优点
-
对性能影响最小,如前文所述,Redis会fork一个子进程去执行保存RDB快照的操作,几乎不影响Redis处理客户端请求的效率。
-
每次快照会生成一个完成的数据快照文件,所以可以辅以其它手段保存多个时间点的快照(例如把每天0点的快照备份至其它存储媒介中),作为非常可靠的灾难恢复手段。
-
使用RDB文件进行数据恢复比使用AOF要快很多。
RDB的缺点
-
快照是定期生成的,所以在Redis crash时或多或少会丢失一部分数据。
-
如果数据集非常大,且CPU不够强(比如单核CPU),Redis在fork子进程时,可能会消耗相对较长的时间(长至1秒),影响期间的客服端请求
AOF日志(Append Only File)
AOF日志是一种增量备份日志,它会记录Redis服务端执行的所有指令,当系统重启时,通过读取AOF日志的方式,再次执行所有指令,来达到恢复数据的目的。
AOF日志是写后日志,即先执行命令,再写入内存,最后记录日志,和Mysql的先写日志、再写磁盘的写前日志恰恰相反。这么做的目的,主要是为了过滤不正确的语法指令,避免恢复数据时出错,节省不必要的系统开销。
AOF策略默认是关闭的,如果需要开启,在redis.conf中进行如下配置
appendonly yes
AOF提供了三种fsync配置,可通过配置项 appendfsync 来指定日志写入时机:
appendfsync no:Redis指令执行完成后,先把日志写到内存缓冲区,由操作系统决定何时写入磁盘中,这种策略速度最快,但是主动权不在Redis手中,可能会造成数据丢失,不可控性高。
appendfsync always:每执行一条Redis执行,同步写入到磁盘中,这种策略数据安全性最高,但是频繁操作磁盘,影响性能。
appendfsync everysec:Redis指令执行完成后,先把日志写到内存缓冲区,每隔一秒进一次写入磁盘操作,这种策略既可以降低数据丢失风险,又可以减少对Redis性能的影响,是一种兼顾性能和数据安全的折中方案。(Redis默认策略)
AOF重写机制
随着系统的运行,AOF日志必然会臃肿庞大,从而影响数据恢复时间。为此,Redis提供了AOF重写机制,只保留能够把数据恢复到最新状态的最小写操作集。可以通过BGREWRITEAOF命令触发,也可以配置Redis定期自动执行:
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
上面两行配置的含义是,Redis在每次AOF rewrite时,会记录完成rewrite后的AOF日志大小,当AOF日志大小在该基础上增长了100%后,自动进行AOF rewrite。同时如果增长的大小没有达到64mb,则不会进行rewrite。
AOF的优点
-
最安全,在启用appendfsync always时,任何已写入的数据都不会丢失,使用在启用appendfsync everysec也至多只会丢失1秒的数据。
-
AOF文件在发生断电等问题时也不会损坏,即使出现了某条日志只写入了一半的情况,也可以使用redis-check-aof工具轻松修复。
-
AOF文件易读,可修改,在进行了某些错误的数据清除操作后,只要AOF文件没有rewrite,就可以把AOF文件备份出来,把错误的命令删除,然后恢复数据。
AOF的缺点
-
AOF文件通常比RDB文件更大
-
性能消耗比RDB高
-
数据恢复速度比RDB慢
混合持久化机制
为了充分发挥AOF日志和RDB快照的优点,同时避免它们的缺点,从Redis4.0开始,提供了一种混合持久化的机制,即将RDB快照和AOF日志文件存放在一起,AOF负责记录两次RDB快照期间发生的增量日志,在服务重启后,Redis先通过RDB快照快速恢复内存数据,然后通过AOF日志恢复滞后部分的增量数据,从而达到全量恢复最新数据的目的。