Redis持久化
Redis支持两种持久化方式:RDB和AOF;
RDB模式
RDB即redis databases,是redis默认的持久化方式;RDB通过快照的方式实现持久化,当满足一定条件时,RDB模式会将内存中的数据生成快照,并存放到磁盘中;
在redis.conf中可以找到默认的快照名称和路径:
实践操作
我们先需要修改下RDB默认的生成快照的策略:
上面默认的策略是:
每隔900秒有1次增删改则生成rdb文件,
每隔300秒有10次增删改则生成rdb文件,
每隔60秒有10000次增删改则生成rdb文件,
为了快速的生成快照文件,改成1秒生成5次;
现在我们先吧dump.rdb文件备份为dump_backup.conf;
在进入redis服务,清除里面的所有数据,并且关掉服务器;
推出服务后我们发现,当前目录下又生成了dump.rdb文件。但是由于我们shutdown时,内存都被清空掉了,所以我们新的dump.rdb没有记录任何实际数据;一会儿真正起到备份恢复作用的还是dump_backup.rdb文件;
因为redis默认会使用名为dump.rdb的文件进行恢复;所以我们把dump.rdb删掉,然后把dump_backup.rdb恢复会dump.rdb,并且重启redis服务,发现数据又恢复了;
注:
- 如果不希望通过修改配置文件,使redis自动同步到dump.rdb中,可以使用save命令,来生成快照文件;
- 当执行:save,bgsave,flushall,shutdown命令时,也会生成快照文件,尤其当flushall,shutdown命令时,会生成一个空数据的快照文件,容易在恢复数据时出现不符合我们预期的情况出现(例如出现没有恢复);
- 当执行关闭redis时(sudo /etc/init.c/redis stop)时,也会生成一个快照文件,数据仍旧为空,并且会覆盖掉我们之前的dump.rdb文件,所以这里也要注意,避免出现不符合我们预期的情况;
- 获取redis安装地址:在服务中,config get dir;
redis生成快照文件的过程为:
- redis会fork一个子进程作为主进程的副本;
- 主进程负责接收并处理客户端请求,子进程负责将内存写入硬盘中的临时文件;
- 待持久化过程结束后,会用此临时文件替换旧的dump.rdb,到此,一次快照生成完毕;
记录一下redis配置文件中关于RDB的项的说明:
stop-writes-on-bgsave-error yes:当后台最后一次保存出错,停止redis的写操作;
rdbcompression yes:当进行持久化时,是否对数据使用LZF进行压缩;
rdbchecksum yes:在存储快照后,是否使用CRC64算法进行数据校验;
dbfilename dump.rdb:指定生成的快照名为dump.rdb;
RDB模式的优缺点:
优点:
- RDB在恢复大数据集时速度比AOF的恢复速度更快;
- RDB可以最大化Redis的性能:父进程在保存RDB文件时唯一要做的事情就是fork出一个子进程,然后子进程会处理接下来的保存工作,父进程无须进行任何I/O操作;
缺点:
- RDB在最后一次之久化结束之后,到服务器发生故障导致的宕机(而此时还未到下一次持久化的节点)之间的数据,会全部丢失;
如果你需要尽量避免服务器故障时丢失数据,那么不适用RDB模式;虽然Redis允许你设置不同的保存点(save point),但是因为RDB文件需要保存整个数据集,所以它并不是一个轻松的操作。因此可能我们设置的save point的间隔稍微长一些,比如5分钟才保存一次RDB文件,在这种情况下,一旦发生故障,你就可能丢失几分钟的数据;
- 每次保存RDB的时候,Redis都要fork()出一个子进程,并由子进程来进行实际的持久化工作。在数据集比较庞大时,fork()可能会非常耗时,造成服务器早某某毫秒内停止处理客户端;如果数据集非常大,而此时的CPU资源非常紧张的话,那么这种停止时间可能会长达1s。虽然AOF重写也要fork()子进程,但无论AOF重写的执行间隔多长,数据的耐久性都不会有任何损失;
AOF模式
AOF即append only file,在AOF模式下,reids会将每一个收到的写命令(包括flushall)都通过write函数追加到appendonly.aof中;
默认情况下redis没有开启AOF模式,AOF的配置在redis.conf中,注释为APPEND ONLY MODE的模块里,如果要开启AOF,需要将appendonly no改为appendonly yes。
实践操作
- 备份一份redis.conf,修改redis.conf中,设置appendonly yes,并且重新启动redis;
- appendfsync指定了如下三种redis进行aof持久化的时机:
- appendfsync always:每次收到写命令就立即强制写入磁盘,性能最低,但是能保证数据的完整性,不推荐使用;
- appendfsync everysec:每秒进行写入,在性能和持久化方面做了很好的折中,推荐;(默认)
- appendfsync no:从不写入,完全依赖os,性能最好,不能保证数据的完整性;
redis对aof新增了一种重写机制,当aof文件大小超过所设定的阈值时,redis会启动对aof文件的内容压缩,只保留可以恢复数据的最小指令集,可以使用命令bgwriteaof手动重写,redis配置的自动重写出发的情景如下:
解读配置:redis会记录上一次aof文件的大小,当aof文件大小超过上一次rewrite后大小的100%(第一个设置-百分比),并且文件大小大雨64MB是触发。如果启动redis后没有发生过重写,记录aof文件的大小就为启动时加载的aof文件的大小;
重写原理:主进程会fork出一条新的进程,对文件重写,遍历新进程的内存数据,每条记录有一条set语句。实际上,重写aof文件的操作并没有读取旧的aof文件,它只针对内存中当前存在的键值重写一个新的aof文件。
两种持久化模式的优先级问题:
- 如果只配置了AOF模式,那么重启redis时只会加载aof文件加载数据;
- 如果同时配置了AOF和RDB模式,那么重启redis时只会加载aof文件加载数据;
- 如果只配置了RDB模式,那么重启redis时只会加载rdb文件加载数据;