Redis和Memcached都是优秀的缓存工具,但是Redis相对于Memcached最大的优势在于Redis可以将内存中缓存的数据持久化到硬盘上,防止数据的丢失。Redis有两种持久化方式,分别是rdb快照持久化方式和aof日志持久化方式。
rdb快照持久化方式
就像它的名字一样,rdb快照持久化方式是对内存中的数据进行定期的快照,并将数据写入二进制文件,默认命名为dump.rdb,名字和存储路径都是可以修改的,在redis.conf中可以对rdb快照方式的开启和一些参数进行配置。
save 900 1 #900秒内,如果有1次写入,则产生快照文件
save 300 1000 #300秒内,如果有1000次写入,则产生快照文件
save 60 10000 #60秒内,如果有10000次写入,则产生快照文件
stop-writes-on-bgsave-error yes #后台备份进程出错时,主进程是否停止写入
rdbcompression yes #导出的rdb文件是否进行压缩
rdbchecksum yes #导入rdb恢复数据时,是否对rdb文件完整性进行校验
dbfilename dump.rdb #导出来的rdb文件的名称
dir ./ #导出的rdb存放路径
Redis默认情况下,rdb快照方式是开启的,如果关闭该持久化方式,只需要注释掉三个save开头的命令即可。rdb因为是定期进行快照,所以可能会出现数据丢失。比如在即将进行下一次快照之前,Redis宕机了,则上一次快照和这一次快照之间做的操作则无法保存,这时就有可能会产生数据丢失。rdb因为其数据是内存数据的映射,所以恢复时可直接载入到内存,恢复数据的速度较快。
aof日志持久化方式
aof日志持久化方式是将Redis的执行命令以日志的方式存储下来,默认名为appendonly.aof,名字可以修改,也可以在文件名前面加路径表示存储目录。aof日志文件存储的是Redis的执行命令,所以恢复时需要重新执行这些命令。
appendonly no #是否打开aof日志功能
appendfilename "appendonly.aof" #生成的日志文件名,默认为appendonly.aof,可以修改,也可以文件名前面加路径
appendfsync everysec #判断同步的频率,有三种方案:always、everysec、no。always是每个命令都立即同步到aof,安全但是速度慢;everysec是每秒同步一次;no是将写入工作交给操作系统,由操作系统判断缓冲区大小,统一写入到aof,频率低但是速度快。
no-appendfsync-on-rewrite yes #正在到处rdb快照的过程中是否停止同步aof
auto-aof-rewrite-percentage 100 #aof文件大小比起上次重写时的大小,增长率为100%时重写
auto-aof-rewrite-min-size 64mb #aof文件大小超过64M时要重写
因为恢复数据需要重新执行所有命令,所以相对于rdb的方式,aof日志形式恢复数据要慢。但是aof日志做快照安全性高,它可以设置多长时间同步aof日志,例如每个命令都同步,或者每隔一秒同步一次,或者由操作系统判断。因为aof同步时需要IO操作,所以同步过于频繁会使得性能下降,Redis默认是每秒同步一次,采取了折中的方式。
aof日志方式会存储所有命令,所以aof日志文件可能会短时间内变得很大,Redis给出两个参数来设置aof日志文件的重写,一个是aof文件大小比起上次重写时大小增长的百分比,另外一个是大小超过多少M之后需要重写。重写是将内存中的数据逆化成命令保存到日志中,每次重写都会对aof日志文件进行压缩,以解决aof日志文件过大的问题。
总结
每种持久化方式都会有其优点和缺点,推荐使用的持久化方式是rdb快照和aof日志形式结合使用,二者互补使得安全性和性能都更高。当aof和rdb方式同时使用时,恢复数据时默认会使用aof日志形式,因为这种形式数据持久化更加靠谱。至于它操作IO性能较慢的问题,可以用主从集群的方式来解决,比如专门设置某一个从节点做aof日志持久化,该从节点只需要保持和主节点数据一致就可以了。