Redis提供了将数据定期自动持久化至硬盘的能力,包括RDB和AOF两种方案,两种方案分别有其长处和短板,可以配合起来同时运行,确保数据的稳定性。
保存数据快照至一个RDB文件中,用于持久化。RDB操作和Mysql Dump相似。
注意:
如果机器上运行多个Redis,需要配置RDB文件名称,否则多个Redis的RDB文件会相互覆盖。除了上述三种执行方式,以下情况也会生成RDB文件:
主从的全量复制时,主机会生成RDB文件。Redis中的debug reload提供debug级别的重启,不清空内存的一种重启,这种方式也会触发RDB文件的生成。执行shutdown时,会触发RDB文件的生成。采用AOF持久方式时,Redis会把每一个写请求都记录在一个日志文件里,AOF操作和Mysql Binlog相似。通过AOF重写机制减少AOF文件的体积,从而减少恢复时间。
为了解决AOF文件体积膨胀的问题,Redis提供了AOF重写功能:Redis服务器可以创建一个新的AOF文件来替代现有的AOF文件,新旧两个文件所保存的数据库状态是相同的,但是新的AOF文件不会包含任何浪费空间的冗余命令,通常体积会较旧AOF文件小很多。
AOF重写并不需要对原有AOF文件进行任何的读取,写入,分析等操作,这个功能是通过读取服务器当前的数据库状态来实现的。
[外链图片转存失败(img-8fuQiQR2-1563546641258)(http://mseddl.gitee.io/photos/backend/redis/redis-start.png)]
Redis启动数据加载流程:
AOF持久化开启且存在AOF文件时,优先加载AOF文件。AOF关闭或者AOF文件不存在时,加载RDB文件。加载AOF/RDB文件成功后,Redis启动成功。AOF/RDB文件存在错误时,Redis启动失败并打印错误信息。fork()的实际开销就是复制父进程的页表以及给子进程创建一个进程描述符,所以速度一般比较快
内存量越大,耗时越长;物理机相对较快,虚拟机相对较慢。
但如果AOF重写期间,Redis宕机的话,在Linux的系统默认配置下,最多会丢失30s的数据。如果无法忍受数据丢失,no-appendfsync-on-rewrite配置no;如果应用系统无法忍受延迟,而可以容忍少量的数据丢失,则设置为yes。
根据写入量决定磁盘类型:例如ssd单机多实例持久化文件目录可以考虑分盘,或者使用类似cgroups机制进行硬盘资源的合理分配例如在AOF的everysec策略中,主线程会对比上次fsync的时间,如果距离上次fsync时间超过两秒,就会造成主线程阻塞(等待同步线程同步完成)。
日常开发可以使用info persistence命令,查看历史发生AOF阻塞的次数;然而需要了解AOF追加阻塞的发生时间则需要查看Redis日志。
发送AOF追加阻塞的时候,日志如下:
Asynchronous AOF fsync is taking too long (disk is busy?). Writing the AOF buffer without waiting for fsync to complete, this may slow down Redis.
优化方法(参考其他方面的优化点)