Redis的三种持久化策略及选取建议
概述
Redis是一个基于内存的高性能的键值型数据库,它支持三种不同的持久化策略:RDB(快照)、AOF(追加文件)、混合。这三种策略各有优缺点,需要根据不同的场景和需求进行选择和配置。本文将介绍这三种策略
RDB(快照)
概述
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文件是一个紧凑的二进制文件,占用空间小,传输速度快,适合做备份和灾难恢复
- RDB文件恢复数据的速度比AOF快,因为只需要加载一次文件即可
- RDB持久化对Redis服务器的性能影响较小,因为大部分工作由子进程完成
RDB持久化策略的缺点有:
- RDB文件不能实时或者近实时地反映Redis内存中的数据,因为它是定时触发的。如果在两次快照之间发生故障,可能会丢失一部分数据
- RDB文件在生成过程中可能会占用较多的内存和CPU资源,因为需要复制主进程的内存并执行压缩操作
AOF(追加文件)
概述
AOF持久化策略是指将Redis服务器执行的每一条写命令都记录到一个文本文件中,这个文本文件就是一个追加文件(append only file)
AOF有三种持久化策略,也就是刷盘策略。可以根据不同的场景使用不同的刷盘策略。
然而随着时间的推移,AOF文件也会越来越大,因为它记录了所有的写命令。这样会导致AOF文件占用过多的磁盘空间,以及恢复数据的时间过长。为了解决这个问题,Redis提供了AOF重写机制,来压缩和优化AOF文件。
优缺点
AOF持久化策略的优点有:
- AOF文件可以实时或者近实时地记录Redis内存中的数据,因为它是每次写命令或者每秒钟同步一次。如果在同步之间发生故障,可能会丢失一部分数据,但是数据丢失的概率比RDB小。
- AOF文件是一个文本文件,可以方便地查看和编辑。AOF文件中的命令是Redis协议格式的,可以直接用Redis客户端来执行。
- AOF文件可以自动进行重写,以减少冗余命令和文件体积。重写过程不影响Redis服务器的正常服务,也不会丢失任何数据。
AOF持久化策略的缺点有:
- AOF文件通常比RDB文件大,占用更多的磁盘空间
- AOF文件恢复数据的速度比RDB慢,因为需要重新执行所有的命令
- AOF文件在写入过程中可能会出现数据不一致的情况,例如命令只写入了一半或者写入了错误的命令。这种情况下需要用redis-check-aof工具来修复AOF文件
AOF刷盘策略
当Redis重启时,可以通过重新执行追加文件中的命令来恢复数据。AOF持久化策略可以通过配置文件来开启和设置,它决定了写命令记录到AOF文件的频率。有三个选项:
- no:写入缓存,什么时候刷盘由redis决定
- everysec:每隔一秒刷一次盘
- always:写入缓存时同时写入磁盘(尽快刷盘,而不是实时刷盘)
以下是三个策略的对比:
| 类型 | 数据安全性 | 性能 |
| no | 低 | 高 |
| everysec | 较高 | 较高 |
| always | 高 | 低 |
AOF重写
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文件内
- 将新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
- AOF与RDB混合
他们各有优缺点,需要结合不同的应用场景综合考虑,首先先讲解AOF和RDB的选择,再讲解混合模式
AOF和RDB的选择
在Redis中,AOF和RDB两种持久化方式各有优缺点,一般来说,有以下几个方面需要参考:
- 数据安全性:如果要求数据不丢失,推荐AOF
- AOF可以采取每秒同步一次数据或每次写操作都同步用来保证数据安全性
- 如果使用每秒同步一次策略,则最多丢失一秒的数据
- 如果使用每次写操作都同步策略,安全性达到了极致,但这会影响性能
- RDB是一个全量的二进制文件,恢复时只需要加载到内存即可,但是可能会丢失最近几分钟的数据(取决于RDB持久化策略)
- AOF可以采取每秒同步一次数据或每次写操作都同步用来保证数据安全性
- 数据恢复速度:如果要求快速恢复数据,推荐RDB
- AOF需要重新执行所有的写命令,恢复时间会更长
- RDB是一个全量的二进制文件,恢复时只需要加载到内存即可
- 数据备份和迁移:如果要求方便地进行数据备份和迁移,推荐RDB
- AOF文件可能会很大,传输速度慢
- RDB文件是一个紧凑的二进制文件,占用空间小,传输速度快
- 数据可读性:如果要求能够方便地查看和修改数据,推荐AOF
- AOF是一个可读的文本文件,记录了所有的写命令,可以用于灾难恢复或者数据分析
- RDB是一个二进制文件,不易查看和修改
| 数据安全性 | 数据恢复速度 | 数据备份和迁移 | 数据可读性 | |
|---|---|---|---|---|
| AOF | 高 | 低 | 低 | 高 |
| RDB | 低 | 高 | 高 | 低 |
AOF与RDB的混合模式
综合上一节,我们可以根据不同的场景和需求来选择合适的持久化方式。但是,在实际应用中,并不一定要二选一,也可以同时使用AOF和RDB两种持久化方式。这样可以利用AOF来保证数据不丢失,作为数据恢复的第一选择;用RDB做不同程度的冷备份,当AOF备份文件丢失或损坏不可用时,可以使用RDB快照文件快速地恢复数据
综上所述,混合模式兼并了RDB重启后的快速恢复能力和AOF丢失数据风险低的能力,具体操作流程如下:
- 子进程会通过
BGSAVE写入AOF中 - 触发
BGREWRITEAOF后,会将AOF写入到文件 - 将含有RDB和AOF的数据覆盖旧的AOF文件(这时AOF文件一半为RDB,一半为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两种持久化方式也需要注意一些问题:
- AOF重写和RDB持久化可能会同时发生冲突,导致内存、CPU和磁盘的消耗增加。为了解决这个问题,Redis采用了一些策略来协调两者之间的关系。具体可以参考下面的介绍(AOF重写和RDB持久化的冲突)
- AOF文件可能会变得很大,导致磁盘空间不足或者恢复时间过长。为了解决这个问题,Redis提供了AOF重写机制来压缩AOF文件。具体可以参考上一节(AOF重写)
- AOF文件可能会被损坏或者丢失,导致数据无法恢复。为了解决这个问题,Redis提供了AOF校验机制来检测AOF文件是否完整。具体可以参考下面的介绍(AOF校验机制)
AOF重写和RDB持久化的冲突
在Redis中,AOF重写和RDB持久化可能会同时发生,这会导致一些冲突和问题。例如:
- AOF重写和RDB持久化都需要fork子进程,如果两个子进程同时存在,会增加内存的消耗和系统的负载。
- AOF重写和RDB持久化都需要写入磁盘,如果两个文件同时写入,会增加磁盘的压力和IO的开销。
- AOF重写和RDB持久化都需要在完成后通知主进程,如果两个信号同时到达,可能会造成信号丢失或者处理错误。
为了解决这些冲突和问题,Redis采用了以下策略:
- 如果AOF重写和RDB持久化同时被触发,那么只有一个子进程会被创建,优先执行RDB持久化,然后再执行AOF重写。这样可以避免同时存在两个子进程的情况。
- 如果AOF重写正在进行,而此时又收到了RDB持久化的请求,那么RDB持久化会被延迟到AOF重写完成后再执行。这样可以避免同时写入两个文件的情况。
- 如果AOF重写和RDB持久化都完成了,那么主进程会先处理RDB持久化的信号,然后再处理AOF重写的信号。这样可以避免信号丢失或者处理错误的情况。
总之,Redis通过优先级、延迟和顺序等方式来协调AOF重写和RDB持久化的冲突和问题,保证了数据的完整性和一致性,下图为简要说明。
| 场景 | 策略 |
|---|---|
| AOF重写与RDB持久化同时被触发 | 优先RDB |
| AOF重写正在进行 | 优先AOF |
| AOF重写和RDB持久化都完成 | 优先RDB |
AOF校验机制
AOF校验机制是指在Redis启动时,对AOF文件进行检查,判断文件是否完整,是否有损坏或者丢失的数据。如果发现AOF文件有问题,Redis会拒绝启动,并给出相应的错误信息
AOF校验机制的原理是使用一个64位的校验和(checksum)来对AOF文件进行验证。校验和是一个数字,它是根据AOF文件的内容计算出来的,如果AOF文件的内容发生了任何改变,那么校验和也会发生变化。因此,通过比较计算出来的校验和和保存在AOF文件末尾的校验和,就可以判断AOF文件是否完整。
具体来说,AOF校验机制的过程如下:
- 当Redis执行AOF重写时,它会在新的AOF文件末尾写入一个特殊的命令:
*1\r\n$6\r\nCHECKSUM\r\n,这个命令表示接下来要写入一个校验和 - Redis会使用CRC64算法,对新的AOF文件中除了最后一行之外的所有内容进行计算,得到一个64位的数字作为校验和,并将这个数字以16进制的形式写入到新的AOF文件末尾。
- Redis会将新的AOF文件替换旧的AOF文件,并将校验和保存在内存中
- 当Redis重启时,它会读取AOF文件,并使用同样的CRC64算法,对除了最后一行之外的所有内容进行计算,得到一个64位的数字作为校验和,并将这个数字与内存中保存的校验和进行比较
- 如果两个校验和相同,说明AOF文件没有损坏或者丢失数据,Redis会继续启动并加载AOF文件中的数据
- 如果两个校验和不同,说明AOF文件有问题,Redis会拒绝启动,并给出类似于
Bad file format reading the append only file: checksum mismatch这样的错误信息
通过这种方式,Redis可以保证在启动时检测到AOF文件是否完整,从而避免加载错误或者不完整的数据。当然,这种机制也有一些局限性:
- AOF校验机制只能在Redis启动时执行,如果在运行过程中AOF文件被修改或者损坏,Redis无法及时发现。
- AOF校验机制只能检测到AOF文件是否完整,但不能检测到AOF文件是否正确。比如说,如果有人恶意地修改了AOF文件中的某些命令或者参数,导致数据逻辑上出现错误,那么Redis无法识别出这种情况。
- AOF校验机制会增加Redis启动时的时间开销,因为需要对整个AOF文件进行计算。如果AOF文件很大,那么这个过程可能会很慢。
总之,AOF校验机制是一种简单而有效的方法,可以保证在Redis启动时检测到AOF文件是否完整。但是它也有一些局限性和代价,需要在实际应用中权衡利弊。
三种模式的选择建议
具体的选择建议如下:
- 如果对数据完整性要求不高,可以只使用RDB,或者将AOF的同步频率设置为每秒一次
- 如果想让数据尽可能不丢失,可以只使用AOF,并将AOF的同步频率设置为每次写入操作都同步
- 如果对数据完整性和性能都有要求,可以同时使用AOF和RDB,并将AOF的同步频率设置为每秒一次。这样既可以保证数据的安全性,又可以利用RDB进行快速的数据恢复
- 如果既想节省磁盘空间,又想提高数据恢复速度,可以只使用RDB,并适当调整RDB的快照频率
AOF和RDB两种持久化方式各有优缺点,需要根据具体的场景和需求来进行选择和配置。在选择时,需要考虑以下几个因素:
- 数据完整性:即数据丢失的风险和可接受的范围
- 数据恢复速度:即从持久化文件恢复到内存中所需的时间
- 磁盘空间占用:即持久化文件所占用的磁盘空间大小
- 写入性能:即持久化操作对Redis服务端的写入性能的影响
注意:
AOF策略设置为 always 或 everysec,并且BGSAVE或BGREWRITEAOF正在对磁盘执行大量 I/O 时,Redis 刷盘可能会阻塞
可以设置no-appendfsync-on-rewrite yes,来缓解这个问题。这样的话,当另一个子进程正在保存的时候,Redis 的持久性与appendfsync no相同。实际上,最严重的情况是丢失30秒的日志
持久化策略常见问题及解决方案
AOF文件过大
当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文件损坏
当AOF文件损坏时,会导致Redis无法正常启动或者恢复数据。可以使用redis-check-aof工具来修复AOF文件,或者使用备份的RDB文件来恢复数据
AOF 文件可能会被截断
在 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文件丢失
当RDB文件丢失时,会导致Redis无法恢复数据。为了解决这个问题,可以使用备份的AOF文件或者其他节点的RDB文件来恢复数据,或者增加RDB的快照频率来减少数据丢失的风险
RDB文件损坏
当RDB文件损坏时,会导致Redis无法恢复数据。为了解决这个问题,可以使用redis-check-rdb工具来检查和修复RDB文件,或者使用备份的AOF文件或者其他节点的RDB文件来恢复数据
Redis的三种持久化策略及选取建议的更多相关文章
- 基于Redis的三种分布式爬虫策略
前言: 爬虫是偏IO型的任务,分布式爬虫的实现难度比分布式计算和分布式存储简单得多. 个人以为分布式爬虫需要考虑的点主要有以下几个: 爬虫任务的统一调度 爬虫任务的统一去重 存储问题 速度问题 足够“ ...
- Redis两种持久化策略分析
Redis专题地址:https://www.cnblogs.com/hello-shf/category/1615909.html SpringBoot读源码系列:https://www.cnblog ...
- Redis的两种持久化方式-快照持久化和AOF持久化
Redis为了内部数据的安全考虑,会把本身的数据以文件形式保存到硬盘中一份,在服务器重启之后会自动把硬盘的数据恢复到内存(redis)的里边,数据保存到硬盘的过程就称为"持久化"效 ...
- Redis的两种持久化方式-快照持久化(RDB)和AOF持久化
Redis为了内部数据的安全考虑,会把本身的数据以文件形式保存到硬盘中一份,在服务器重启之后会自动把硬盘的数据恢复到内存(redis)的里边,数据保存到硬盘的过程就称为“持久化”效果. redis有两 ...
- Redis 中的数据持久化策略(RDB)
Redis 是一个内存数据库,所有的数据都直接保存在内存中,那么,一旦 Redis 进程异常退出,或服务器本身异常宕机,我们存储在 Redis 中的数据就凭空消失,再也找不到了. Redis 作为一个 ...
- Redis 中的数据持久化策略(AOF)
上一篇文章,我们讲的是 Redis 的一种基于内存快照的持久化存储策略 RDB,本质上他就是让 redis fork 出一个子进程遍历我们所有数据库中的字典,进行磁盘文件的写入. 但其实这种方式是有缺 ...
- 一文掌握Redis的三种集群方案
在开发测试环境中,我们一般搭建Redis的单实例来应对开发测试需求,但是在生产环境,如果对可用性.可靠性要求较高,则需要引入Redis的集群方案.虽然现在各大云平台有提供缓存服务可以直接使用,但了解一 ...
- RabbitMQ(三):消息持久化策略
原文:RabbitMQ(三):消息持久化策略 一.前言 在正常的服务器运行过程中,时常会面临服务器宕机重启的情况,那么我们的消息此时会如何呢?很不幸的事情就是,我们的消息可能会消失,这肯定不是我们希望 ...
- Redis的两种持久化机制
Redis的两种持久化机制 1.持久化机制 client--->redis(内存)--->内存数据-数据持久化--->磁盘 两种方法 快照(Snapshot) AOF(Append ...
- 6_1 持久化模型与再次加载_探讨(1)_三种持久化模型加载方式以及import_meta_graph方式加载持久化模型会存在的变量管理命名混淆的问题
笔者提交到gitHub上的问题描述地址是:https://github.com/tensorflow/tensorflow/issues/20140 三种持久化模型加载方式的一个小结论 加载持久化模型 ...
随机推荐
- Github账户的注册
注册步骤 首先进入github官网界面(注意,只能用Chrome或者Firefox浏览器.这样保险性更强一些) 官网地址:https://github.com/ 映入眼帘的界面是这样的: 点击右上角的 ...
- 设计师必备:免费素材管理工具Billfish v3.0更新了!
Billfish是专门为设计师打造的图片收藏管理工具,可以轻松管理您的各种素材文件.Billfish是一个免费的软件,支持对大量的图片素材进行管理,提供多种快速的检索筛选功能,如颜色,格式,方向, ...
- 自学UI设计有哪些书籍推荐?
自学UI设计大致分为两种情况:其一.业余学习,技能拓展,不以求职为目的;其二.谋生手段,小白进阶学习或者有转行的打算.前者,无论是学习内容或者深度都可以根据自己的需求和兴趣点来做学习选择,相对来说,学 ...
- 基于VirutalBox搭建虚拟机间互通的可访问公网的mini主机群
目标 在单台PC机上安装3+台虚拟机[1] 这些虚拟机间可以相互访问 宿主机[2]与虚拟机可以相互访问 虚拟机可以访问公网 本文将采用 NAT + Host-Only 双网卡的方式实现上述目标,因为采 ...
- Nacos 实现 AP+CP原理[Raft 算法 NO]
来源于网络 一.什么是 Raft算法 Raft 适用于一个管理日志一致性的协议,相比于 Paxos 协议 Raft 更易于理解和去实现它.为了提高理解性,Raft 将一致性算法分为了几个部分,包括领导 ...
- Zookeeper 从入门到精通
更多内容,前往IT-BLOG 一.Zookeeper概述 Zookeeper是一个开源的分布式的,为分布式应用提供协调服务的Apache项目.Zookeeper从设计模式角度来理解:是一个基于观察者模 ...
- HashMap和ConcurrentHashMap扩容过程
HashMap 存储结构 HashMap是数组+链表+红黑树(1.8)实现的. (1)Node[] table,即哈希桶数组.Node是内部类,实现了Map.Entry接口,本质是键值对. 下图链表中 ...
- Conda in Windows under MSYS2 and Zsh 的问题解决
Conda in Windows under MSYS2 and Zsh 的问题解决 在Window11上使用git bash 安装zsh,并配置p10k主题,主要问题就是prompt中无法显示con ...
- node-sass与node版本对照图
- 机器学习08DAY
线性回归 波士顿房价预测案例 步骤 导入数据 数据分割 数据标准化 正规方程预测 梯度下降预测 # 导入模块 import pandas as pd # 导入数据 from sklearn.model ...