Redis持久化
Redis持久化
业务场景
Redis 的数据全部在内存里,如果突然宕机,数据就会全部丢失,因此必须有一种机制来保证 Redis 的数据不会因为故障而丢失,这种机制就是 Redis 的持久化机制。
持久化分类
Redis的持久化分为全量持久化(快照)和增量持久化(AOF 日志)。全量持久化将内存中的数据直接快照存在硬盘中,增量持久化通过记录内存数据修改的日志来实现。AOF 日志在长期的运行过程中会变的无比庞大,数据库重启时需要加载 AOF 日志进行指令重放,这个时间就会无比漫长。所以需要定期进行 AOF 重写,给 AOF 日志进行瘦身。
全量持久化原理
生成快照需要用到文件IO操作,因此 Redis 会开一个子进程来处理文件IO操作。子进程做数据持久化,它不会修改现有的内存数据结构,它只是对数据结构进行遍历读取,然后序列化写到磁盘中。但是父进程(处理用户请求的工作进程)不一样,它必须持续服务客户端请求,然后对内存数据结构进行不间断的修改。
由于父进程会对内存中的数据进行不断修改,为保证子进程数据持久化的顺利进程,父进程的修改内存操作用到了Copy On Write 机制(写时复制)。当父进程对某段内存修改时,会将该内存数据复制一个副本。子进程只需要对这段内存副本的数据做持久化即可。
AOF原理
AOF 日志存储的是 Redis 服务器的顺序指令序列,AOF 日志只记录对内存进行修改的指令记录。Redis 在长期运行的过程中,AOF 的日志会越变越长。如果实例宕机重启,重放整个 AOF 日志会非常耗时,导致长时间 Redis 无法对外提供服务。所以需要对 AOF 日志瘦身。
AOF 日志重写机制可实现日志瘦身,Redis 提供了 bgrewriteaof 指令用于对 AOF 日志进行瘦身。其原理就是开辟一个子进程对内存进行遍历转换成一系列 Redis 的操作指令,序列化到一个新的 AOF 日志文件中。序列化完毕后再将操作期间发生的增量 AOF 日志追加到这个新的 AOF 日志文件中,追加完毕后就立即替代旧的 AOF 日志文件了,瘦身工作就完成了。
使用混合持久化的方式
将全量持久化的文件内容和增量持久化的 AOF 日志文件存在一起。这里的 AOF 日志不再是全量的日志,而是自上一次全量持久化开始到结束的这段时间发生的增量 AOF 日志,通常这部分 AOF 日志很小。在 Redis 重启的时候,可以先加载全量持久化的文件内容,然后再重放增量 AOF 日志就可以完全替代之前的 AOF 全量文件重放,重启效率因此大幅得到提升。