我们知道,Redis的数据是存储在内存中,断电即失,所以Redis大多用作缓存型数据库。但是Redis也是提供了RED持久化和AOF持久化两种方式,来把内存中的数据落盘到磁盘中。下面来主要介绍一下这两种方式。
RDB持久化即通过创建快照(压缩的二进制文件)的方式进行持久化,保存某个时间点的全量数据。RDB持久化是Redis默认的持久化方式。RDB持久化的触发包括手动触发与自动触发两种方式。
Redis会单独创建(fork)一个子进程来进行持久化,会先将数据写入到一个临时文件中,待持久化过程都结束,再用这个临时文件替换上次持久化好的文件。整个过程中,主进程是不进行任何IO操作的(备份由子进程来完成),这就确保了极高的性能,如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加高效。RDB的缺点是最后一次持久化的数据可能丢失。
关于fork
fork是linux系统创建子进程的API,子进程会把父进程的所有数据完全复制,但是这样会极大地消耗linux系统资源,所以Linux系统引入了“写时复制技术”。
写时复制技术:创建子进程并不会拷贝父进程的数据,而是共用。当父进程或子进程对源数据修改时,才会将修改的数据重新复制一份。
AOF(Append-Only-File)持久化即记录所有变更数据库状态的指令,以append的形式追加保存到AOF文件中。在服务器下次启动时,就可以通过载入和执行AOF文件中保存的命令,来还原服务器关闭前的数据库状态。
AOF持久化流程中的文件同步有以下几个策略:
aof 持久化策略会持久化所有修改命令;里面的很多命令其实可以合并或者删除;
aof rewrite 在 aof 的基础上,满足一定策略则 fork 进程,根据当前内存状态,转换成一系列
的 redis 命令,序列化成一个新的 aof 日志文件中,序列化完毕后再将操作期间发生的增量 aof 日
志追加到新的 aof 日志文件中国你,追加完毕后替换旧的 aof 日志文件;以此达到对 aof 日志瘦
身的目的;
注意:aof rewrite 开启的前提是开启 aof;
AOF重写是对原AOF文件大小的缩减,原理是通过计算所有的命令最终将命令缩为最简。
例如:
原文件:set k1 v1 set k2 v2 set k1 v2
重写后的文件:set k1 v2 set k2 v2
AOF持久化流程中的文件重写可以手动触发,也可以自动触发。重写过程在子进程中进行。
从上面知道,rdb 文件小且加载快但丢失多,aof 文件大且加载慢但丢失少;混合持久化是吸取
rdb 和 aof 两者优点的一种持久化方案;
持久化期间修改的数据以 aof 的形式附加到文件的尾部;
混合持久化实际上是在 aof rewrite 基础上进行优化;所以需要先开启 aof rewrite;
如果Redis只是用来做缓存服务器,比如数据库查询数据后缓存,那可以不用考虑持久化,因为缓存服务失效还能再从数据库获取恢复。
如果你要想提供很高的数据保障性,那么建议你同时使用两种持久化方式。
如果你可以接受灾难带来的几分钟的数据丢失,那么可以仅使用RDB。
通常的设计思路是利用主从复制机制来弥补持久化时性能上的影响。即Master上RDB、AOF都不做,保证Master的读写性能,而Slave上则同时开启RDB和AOF(或4.0以上版本的混合持久化方式)来进行持久化,保证数据的安全性。