Redis 有两种持久化方案,RDB (Redis DataBase)和 AOF (Append Only File)
一:什么是AOF ?
AOF 全称是Append Only File,是 redis 记录执行指令的日志文件。
1. 工作原理
将写操作追加到文件中,AOF 日志是写后日志,“写后”的意思是 Redis 是先执行命令,把数据写入内存后,然后才记日志;里面记录的是指令执行的步骤,非常详细,描绘出了数据的变化过程。
2. AOF相关参数配置
参数配置在 redis.conf 文件里。
- appendonly no # 默认是no 表示不开启AOF机制,yes 代表开启
- appendfilename "appendonly.aof" # aof文件名,默认是"appendonly.aof"
- appendfsync everysec #aof持久化策略的配置,下文会详述
-
no-appendfsync-on-rewrite no # 是重写机制的相关参数,下文会说明
-
auto-aof-rewrite-percentage 100 # 是重写机制的相关参数,下文会说明
-
auto-aof-rewrite-min-size 64mb # 是重写机制的相关参数,下文会说明
- aof-use-rdb-preamble no # Redis从4.0开始就提出了一个混合使用 AOF 日志和内存快照的开关
3. AOF持久化策略
就是当数据被写入内存后,如何再写到文件的策略(为什么要写入文件,因为不持久化,redis挂了后,内存的数据没了,数据就丢了)
关于持久化同步时间节点上的控制有三个参数选项:
appendfsync always 表示不执行同步,由操作系统自己选择时间保证数据同步到磁盘,速度最快;
appendfsync everysec 表示每一秒执行一次同步,可能会导致丢失这1s数据
appendfsync no 表示每次写入内存后都执行同步,以保证数据同步到磁盘;
4. AOF的重写机制
很显然,因为AOF文件需要记录每一步的操作步骤,所以文件的冗余内容会越来越多。所以聪明的 Redis 新增了重写机制。当AOF文件的大小超过所设定的阈值时,Redis就会对AOF文件的内容压缩。
重写的原理:Redis 会fork出一条新进程,读取当前内存中的数据,并重新写到一个临时文件中,这里没有读取旧文件(你都那么大了,我还去读你???),最后替换旧的aof文件。AOF 文件是以追加的方式,逐一记录接收到的写命令的。当一个键值对被多条写命令反复修改时,AOF 文件会记录相应的多条命令。但是在重写的时候,是根据这个键值对当前的最新状态,为它生成对应的写入命令。这样一来,一个键值对在重写的新日志中只用一条命令就行了,而且,在日志恢复时,只用执行这条命令,就可以直接完成这个键值对的写入了。所以新的AOF文件大小会大大缩小。
重写触发机制:当AOF文件大小是上次rewrite后大小的一倍且文件大于64M时触发。这里的“一倍”和“64M” 可以通过配置文件修改。
- auto-aof-rewrite-percentage 100
默认值为100。aof自动重写配置,当目前aof文件大小超过上一次重写的aof文件大小的百分之多少进行重写,即当aof文件增长到一定大小的时候,Redis能够调用bgrewriteaof对日志文件进行重写,100代表大于一倍。
- auto-aof-rewrite-min-size 64mb
设置允许重写的最小aof文件大小,避免了达到约定百分比但尺寸仍然很小的情况还要重写,意思就是至少达到64mb,才重写
当redis宕机重启后,会读取 "appendonly.aof" 文件,将数据刷回到内存中去。
二:什么是RDB ?
这里解释为内存快照,就是指内存中的数据在某个时刻的状态记录。
1. 工作原理
RDB 是 Redis 默认的持久化方案。在指定的时间间隔内,执行指定次数的写操作,则会将内存中的数据写入到磁盘中。即在指定目录下生成一个dump.rdb文件。Redis 重启会通过加载dump.rdb文件恢复数据。与上述的aof相比,aof是持续的叠加写入,而RDB是整体写入,相当于给内存的数据拍下了一张张照片。
2. AOF相关参数配置
参数配置在 redis.conf 文件里。
- # save:这里是用来配置触发 Redis的持久化条件,也就是什么时候将内存中的数据保存到硬盘。默认如下配置
save 900 1 #表示900 秒内如果至少有 1 个 key 的值变化,则保存save 300 10 #表示300 秒内如果至少有 10 个 key 的值变化,则保存save 60 10000 #表示60 秒内如果至少有 10000 个 key 的值变化,则保存
-
# 默认值为yes。当启用了RDB且最后一次后台保存数据失败,Redis是否停止接收数据。这会让用户意识到数据没有正确持久化到磁盘上,否则没有人会注意到灾难(disaster)发生了。如果Redis重启了,那么又可以重新开始接收数据了stop-writes-on-bgsave-error yes
-
# 默认值是yes。对于存储到磁盘中的快照,可以设置是否进行压缩存储。如果是的话,redis会采用LZF算法进行压缩。如果你不想消耗CPU来进行压缩的话,可以设置为关闭此功能,但是存储在磁盘上的快照会比较大。rdbcompression yes
-
# 默认值是yes。在存储快照后,我们还可以让redis使用CRC64算法来进行数据校验,但是这样做会增加大约10%的性能消耗,如果希望获取到最大的性能提升,可以关闭此功能。rdbchecksum yes
-
# 设置快照的文件名,默认是 dump.rdbdbfilename dump.rdb
-
# 设置快照文件的存放路径,这个配置项一定是个目录,而不能是文件名。使用上面的 dbfilename 作为保存的文件名。dir /usr/local/var/db/redis/
3. RDB的优缺点
优点:
适合大规模的数据恢复,如果业务对数据完整性和一致性要求不高,RDB是很好的选择。
缺点:
数据的完整性和一致性不高,因为RDB可能在最后一次备份时宕机了。
三:总结
- Redis 默认开启RDB持久化方式,在指定的时间间隔内,执行指定次数的写操作,则将内存中的数据写入到磁盘中。
- RDB 持久化适合大规模的数据恢复但它的数据一致性和完整性较差。
- Redis 需要手动开启AOF持久化方式,默认是每秒将写操作日志追加到AOF文件中。
- AOF 的数据完整性比RDB高,但记录内容多了,会影响数据恢复的效率。
- Redis 针对 AOF文件大的问题,提供重写的瘦身机制。
- 若只打算用Redis 做缓存,可以关闭持久化。
- 若打算使用Redis 的持久化。建议RDB和AOF都开启。其实RDB更适合做数据的备份,留一后手。AOF出问题了,还有RDB。
优化建议:
1. 数据不能丢失时,内存快照和 AOF 的混合使用是一个很好的选择;
2. 如果允许分钟级别的数据丢失,可以只使用 RDB;
3. 如果只用 AOF,优先使用 everysec 的配置选项,因为它在可靠性和性能之间取了一个平衡。