1、简介

持久化是支撑Redis高可用的重要基础。试想如果Redis不支持持久化,不管你部署的Redis是单点、主从、哨兵还是集群,只要系统掉电或者发生其他灾难,Redis中的数据就丢失了。Redis持久化包括RDB和AOF两种方式。

2、RDB

保存当前内存数据的快照。

2.1 触发方式:手动、自动

手动触发:执行save或者bgsave命令

自动触发:配置save m n

手动触发的save和bgsave的区别:

save会阻塞主进程,生成RDB快照后,才能继续处理新的请求。(Redis单线程模型),当输入save命令时,客户端显示状态如下:

redis 的save 配置 redis的save和bgsave_Redis

bgsave:fork子进程来生成RDB快照,只有fork子进程的时候才会阻塞,创建子进程成功后,主进程就可以继续处理新的请求。执行bgsave命令,客户端打印如下信息:

redis 的save 配置 redis的save和bgsave_RDB_02

自动触发的save配置与手动触发的save命令的区别。自动触发的save m n表示的是在m秒后,若发生了n次写操作,就触发一次RDB,这里的save实际上是通过bgsave实现的。

2.2 RDB配置

通常通过在Redis.conf中配置save m n来实现。Redis默认开始RDB持久化,其配置如下图所示:

redis 的save 配置 redis的save和bgsave_AOF_03

也就是说,1)900秒发生一次写操作;2)300秒内发生10次写操作;3)60秒后发生10000次写操作,三种场景都会触发RDB。

2.3 RDB实现原理

bgsave是Redis推荐使用的RDB持久化方式。这里主要介绍bgsave的流程。

redis 的save 配置 redis的save和bgsave_redis 的save 配置_04

简单来说,bgsave命令会触发5个动作的执行:

1)客户端发送bgsave命令给Redis;

2)redis父进程判断是否有其他正在执行中的RDB或者AOF子进程,如果有则返回结束,如果没有则跳转3);

3)父进程fork子进程,在此期间父进程阻塞,不能处理其他请求;

4)父进程创建子进程结束并且父进程继续响应其他请求;

5)子进程生成RDB文件

2.4 RDB 优缺点

RDB保存的是二进制文件,用RDB恢复数据比AOF快。

RDB保存的是内存中数据的快照,由于每次都是fork子进程来执行内存数据的全量,比较耗费资源,因此不能实时保存数据。

3、 AOF

类似MySQL binlog机制,记录的是每条写操作。解决RDB不能实时持久化的问题。

3.1 AOF配置

Redis默认只开启了RDB持久化方式,可以通过设置appendonly为yes开启AOF持久化。

3.2 AOF实现原理

redis 的save 配置 redis的save和bgsave_Redis_05

AOF写入流程分为三个部分:

1)服务端收到命令写入请求,先将命令写入aof缓冲区;

2)Redis根据文件同步策略将aof缓冲区中的数据追加到AOF文件;

3)当满足一定的条件触发AOF文件rewrite。

3.3 为什么现将命令写入aof缓冲区,而不是直接写到文件中?

写入文件的操作是阻塞的,如果每次的命令都直接写到AOF文件中,那么肯定导致Redis性能急剧下降。将命令先写入aof缓存区有什么好处呢?Redis将数据写入aof缓冲区就可以返回处理其他新的请求,而同步缓冲区数据到AOF文件的操作由配置的同步策略来完成,可以更加灵活的配置实现性能和负载均衡。

3.4 AOF的文件同步策略

AOF支持三种文件同步策略,通过配置appendfsync参数实现:1)no;2)everysec;3)always。

1)no,表示Redis将命令写入aof缓冲区就不管了,由操作系统自己调度决定什么时候将aof缓冲区中的数据同步到AOF文件中。不推荐使用,因为这种配置将同步交给操作系统,如果在同步之前操作系统挂了,将导致aof缓冲区中的数据全部丢失;

2)everysec,表示Redis将命令写入aof缓冲区后,每秒调度一次操作系统fync来同步数据到AOF文件,推荐使用的方式,能够保证较高的吞吐

3)always,表示Redis将命令写入aof缓冲区后,马上调用fsync命令将缓冲区中的数据同步到AOF文件,不推荐使用,fsync是阻塞操作,数据写如磁盘才能返回,每条命令都调用,将导致Redis性能大大降低。

3.5 AOF重写机制

3.5.1 AOF重写配置

Redis只持有一份AOF文件,所有的写请求都会同步到这个AOF文件中,也就是说AOF文件会不断变大。当满足一定条件时,会触发AOF的重写机制。那么这个条件时什么呢?

AOF重写分为手动重写和自动重写两种方式。手从重写是执行bgrewriteaof命令,自动重写redis提供了两个参数来控制。auto-aof-rewrite-min-size和auto-aof-rewrite-percentage。

auto-aof-rewrite-min-size:表示重写AOF文件必须满足的最小大小,默认为64MB;

auto-aof-rewrite-percentage:表示当前aof文件的大小和上一次重写后aof文件大小的比值。

自动重写的触发时机:

1)当前aof文件大小>auto-aof-rewrite-min-size;

2)当前aof文件相较于上次重写后aof文件增加的大小相比上次重写后aof文件的大小比值大于等于auto-aof-rewrite-percentage

3.5.2 AOF重写原理

aof重写流程如下图所示:

redis 的save 配置 redis的save和bgsave_RDB_06

主要分为7个步骤:

1)Redis服务端收到aofrewrite请求

2)父进程fork,阻塞创建子进程

3)父进程创建子进程成功,由子进程将fork时Redis中的数据写入新的AOF问阿金,父进程继续将数据写数据写入aof缓冲区,根据配置的aof文件同步策略将aof缓冲区数据同步到旧AOF文件

4)同时,父进程将fork创建子进程后的数据写到aof重写缓冲区

5)子进程同步完fork时候的数据,通知父进程

6)父进程将aof重写缓冲区中的数据同步到新的AOF文件

7)用新的AOF文件替换旧AOF文件,完成重写

3.6 AOF的优缺点

相较于RDB,能够保存更加完整的数据;

比RDB恢复慢。

4、数据恢复

Redis支持同时开启RDB和AOF两种持久化方式。当都配置后,Redis重启,数据恢复流程如图所示:

redis 的save 配置 redis的save和bgsave_AOF_07

简单来说,什么意思呢?Redis重启,首先检测是否配置AOF,如果配置且存在AOF文件,那么用AOF文件恢复数据,如果不存在AOF文件,检查是否存在RDB文件,如果存在,则用RDB文件恢复数据。

 

THE END.

 

参考《Redis开发与运维》