Redis是一个基于内存的高性能的键值型数据库,它支持三种不同的持久化策略:RDB(快照)、AOF(追加文件)、混合。这三种策略各有优缺点,需要根据不同的场景和需求进行选择和配置。本文将介绍这三种策略
RDB持久化策略是指在一定的时间间隔内,将Redis内存中的数据以二进制文件的形式保存到硬盘上。这个二进制文件就是一个快照,它记录了某个时刻Redis内存中的所有数据。RDB持久化策略可以通过配置文件或者命令来触发,配置文件中可以设置多个条件,当任意一个条件满足时,就会执行一次快照操作。如下所示:
save 900 1 # 900秒内执行一次 set 操作 则持久化1次
save 300 10 # 300秒内执行10次 set 操作,则持久化1次
save 60 10000 # 60秒内执行10000次 set 操作,则持久化1次
命令有两种:
save
:不建议使用,会阻塞redis服务的进程,直到成功创建RDB文件bgsave
:父进程创建一个子进程生成RDB文件,父进程可以正常处理客户端的指令,不影响主进程的服务RDB持久化策略的优点有:
RDB持久化策略的缺点有:
AOF持久化策略是指将Redis服务器执行的每一条写命令都记录到一个文本文件中,这个文本文件就是一个追加文件(append only file)
AOF有三种持久化策略,也就是刷盘策略。可以根据不同的场景使用不同的刷盘策略。
然而随着时间的推移,AOF文件也会越来越大,因为它记录了所有的写命令。这样会导致AOF文件占用过多的磁盘空间,以及恢复数据的时间过长。为了解决这个问题,Redis提供了AOF重写机制,来压缩和优化AOF文件。
AOF持久化策略的优点有:
AOF持久化策略的缺点有:
当Redis重启时,可以通过重新执行追加文件中的命令来恢复数据。AOF持久化策略可以通过配置文件来开启和设置,它决定了写命令记录到AOF文件的频率。有三个选项:
以下是三个策略的对比:
类型 | 数据安全性 | 性能 |
no | 低 | 高 |
everysec | 较高 | 较高 |
always | 高 | 低 |
AOF重写机制的原理是:Redis会创建一个新的AOF文件,然后根据内存中的当前数据状态,生成相应的写命令,并写入到新的AOF文件中。这样新的AOF文件就只包含了最终数据的写命令,而不包含任何无效或者冗余的命令。例如:
# 原始AOF文件
set a 1
set b 2
incr a
del b
set c 3
# 重写后的AOF文件
set a 2
set c 3
上图就是重写前和重写后的文件对比,因为AOF是追加的,是顺序读写(ES也是这样的),所以重写后的命令set a 1
与incr a
变成为set a 2
。为了保证在AOF重写期间的新数据不丢失,Redis中引入了AOF重写缓冲区。当开始执行AOF文件重写之后又接收到客户端的请求命令,不但要将命令写入原本的AOF缓冲区(根据上面提到的参数刷盘),还要同时写入AOF重写缓冲区:
一旦子进程完成了AOF文件的重写,此时会向父进程发出信号,父进程收到信号之后会进行阻塞(阻塞期间不执行任何命令),并进行以下两项工作:
随后,在完成了上面的两项工作之后,整个AOF重写工作完成,父进程开始正常接收命令。
# 文件大小超过上次AOF重写之后的文件的百分比。默认100
# 也就是默认达到上一次AOF重写文件的2倍之后会再次触发AOF重写
auto-aof-rewrite-percentage 100
# 设置允许重写的最小AOF文件大小,默认是64M
# 主要是避免满足了上面的百分比,但是文件还是很小的情况。
auto-aof-rewrite-min-size 64mb
bgrewriteaof
命令。Redis现有的持久化策略有三种:
他们各有优缺点,需要结合不同的应用场景综合考虑,首先先讲解AOF和RDB的选择,再讲解混合模式
在Redis中,AOF和RDB两种持久化方式各有优缺点,一般来说,有以下几个方面需要参考:
数据安全性 | 数据恢复速度 | 数据备份和迁移 | 数据可读性 | |
---|---|---|---|---|
AOF | 高 | 低 | 低 | 高 |
RDB | 低 | 高 | 高 | 低 |
综合上一节,我们可以根据不同的场景和需求来选择合适的持久化方式。但是,在实际应用中,并不一定要二选一,也可以同时使用AOF和RDB两种持久化方式。这样可以利用AOF来保证数据不丢失,作为数据恢复的第一选择;用RDB做不同程度的冷备份,当AOF备份文件丢失或损坏不可用时,可以使用RDB快照文件快速地恢复数据
综上所述,混合模式兼并了RDB重启后的快速恢复能力和AOF丢失数据风险低的能力,具体操作流程如下:
BGSAVE
写入AOF中BGREWRITEAOF
后,会将AOF写入到文件混合模式的AOF文件:
REDIS0008?redis-ver4.0.1?redis-bits繞?ctime聮~`?used-mem?? ?aof-preamble??repl-id(6c3378899b63bc4ebeaafaa09c27902d514eeb1f?repl-offset??? list1?77 / appleorangegrape?e k1v1彝髖S[zb*2
$6
SELECT
$1
0
*3
$4
sadd
$8
gamedisk
$4
nioh
*3
$4
sadd
$8
gamedisk
$4
tomb
如果想要开启混合模式,在redis.conf
中配置:
aof-use-rdb-preamble yes
同时使用AOF和RDB两种持久化方式也需要注意一些问题:
在Redis中,AOF重写和RDB持久化可能会同时发生,这会导致一些冲突和问题。例如:
为了解决这些冲突和问题,Redis采用了以下策略:
总之,Redis通过优先级、延迟和顺序等方式来协调AOF重写和RDB持久化的冲突和问题,保证了数据的完整性和一致性,下图为简要说明。
场景 | 策略 |
---|---|
AOF重写与RDB持久化同时被触发 | 优先RDB |
AOF重写正在进行 | 优先AOF |
AOF重写和RDB持久化都完成 | 优先RDB |
AOF校验机制是指在Redis启动时,对AOF文件进行检查,判断文件是否完整,是否有损坏或者丢失的数据。如果发现AOF文件有问题,Redis会拒绝启动,并给出相应的错误信息
AOF校验机制的原理是使用一个64位的校验和(checksum)来对AOF文件进行验证。校验和是一个数字,它是根据AOF文件的内容计算出来的,如果AOF文件的内容发生了任何改变,那么校验和也会发生变化。因此,通过比较计算出来的校验和和保存在AOF文件末尾的校验和,就可以判断AOF文件是否完整。
具体来说,AOF校验机制的过程如下:
*1\r\n$6\r\nCHECKSUM\r\n
,这个命令表示接下来要写入一个校验和Bad file format reading the append only file: checksum mismatch
这样的错误信息通过这种方式,Redis可以保证在启动时检测到AOF文件是否完整,从而避免加载错误或者不完整的数据。当然,这种机制也有一些局限性:
总之,AOF校验机制是一种简单而有效的方法,可以保证在Redis启动时检测到AOF文件是否完整。但是它也有一些局限性和代价,需要在实际应用中权衡利弊。
具体的选择建议如下:
这三种模式各有优缺点,需要根据具体的场景和需求来进行选择和配置。在选择时,需要考虑以下几个因素:
注意:
AOF策略设置为 always 或 everysec,并且BGSAVE
或BGREWRITEAOF
正在对磁盘执行大量 I/O 时,Redis 刷盘可能会阻塞
可以设置no-appendfsync-on-rewrite yes
,来缓解这个问题。这样的话,当另一个子进程正在保存的时候,Redis 的持久性与appendfsync no
相同。实际上,最严重的情况是丢失30秒的日志
当AOF文件过大时,会占用磁盘空间,影响写入性能,甚至导致Redis启动失败。可以使用bgrewriteaof
命令或者配置auto-aof-rewrite-percentage
和auto-aof-rewrite-min-size
参数来触发AOF重写操作,将AOF文件压缩为最小的命令集合
# 文件大小超过上次AOF重写之后的文件的百分比。默认100
# 也就是默认达到上一次AOF重写文件的2倍之后会再次触发AOF重写
auto-aof-rewrite-percentage 100
# 设置允许重写的最小AOF文件大小,默认是64M
# 主要是避免满足了上面的百分比,但是文件还是很小的情况。
auto-aof-rewrite-min-size 64mb
当AOF文件损坏时,会导致Redis无法正常启动或者恢复数据。可以使用redis-check-aof
工具来修复AOF文件,或者使用备份的RDB文件来恢复数据
在 Redis 启动过程中,当 AOF 数据被加载回内存时,可能会发现 AOF 文件在最后被截断
aof-load-truncated yes
,则加载截断的 AOF 文件,并且记录日志aof-load-truncated no
,则服务器会因错误拒绝启动,且需要在启动服务器之前使用redis-check-aof
修复aof文件可以在redis.conf
中配置:
aof-load-truncated yes
可记录时间戳帮助恢复数据
如果在AOF记录时间戳,可能会与现有的AOF解析器不兼容,默认关闭
redis.conf
中配置:
aof-timestamp-enabled no
当RDB文件丢失时,会导致Redis无法恢复数据。为了解决这个问题,可以使用备份的AOF文件或者其他节点的RDB文件来恢复数据,或者增加RDB的快照频率来减少数据丢失的风险
当RDB文件损坏时,会导致Redis无法恢复数据。为了解决这个问题,可以使用redis-check-rdb
工具来检查和修复RDB文件,或者使用备份的AOF文件或者其他节点的RDB文件来恢复数据