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 三种持久化模型加载方式的一个小结论 加载持久化模型 ...
随机推荐
- docker 学习之一 装MySQL 供远程使用 Linux
因为Linux发行版本的问题折腾了好久,尽量使用LTS的版本.其他版本有时候缺的东西太多了,对新手相当不友好. 大概花了几天实在没招了,下了个LTS的版本,再装时正常了.按照官方文档都可以搞定了. 使 ...
- 【LeetCode回溯算法#07】子集问题I+II,巩固解题模板并详解回溯算法中的去重问题
子集 力扣题目链接 给你一个整数数组 nums ,数组中的元素 互不相同 .返回该数组所有可能的子集(幂集). 解集 不能 包含重复的子集.你可以按 任意顺序 返回解集. 示例 1: 输入:nums ...
- Linux系统解压zip包出现中文乱码问题
1. 使用指定GBK编码格式进行解压可以使用如下指定编码格式进行解压. unzip -O GBK 资料.zip 或者使用CP936也是可以指定GBK编码格式进行解压 unzip -O CP936 资料 ...
- Spring--注解开发定义Bean
注解开发 先看一看之前的bean的做法: 所谓注解开发,当然就要用到注解啊,就是在BookDao接口的实现类里面进行注解的定义 如图所示: 而在.xml文件里面,就需要进行这样一个操作: 注解当然不会 ...
- 除select外查询数据的另一种姿势
1.24 1.[GYCTF2020]Blacklist buuctf上的题目 1.解题过程 输入1会返回一个数组,加上单引号就报错了,说明存在注入 以前做过类似的估计是堆叠注入,尝试一下 注入成功 正 ...
- 音频的价值、AI Codec 的意义与算法能力的边界丨一期一会 • 音频工程师专场
前言 音频技术发展到今天,经历了从模拟音频到数字音频到历程.国际音频工程师协会创建于 1948 年,中国数字音频技术起步相对较晚,长期被国外组织和公司垄断.随着中国的不断发展.科技日益进步,经过近三十 ...
- Python的安装与配置(图文教程)
安装Python 想要进行Python开发,首先需要下载和配置Python解释器. 下载Python 访问Python官网: https://www.python.org/ 点击downloads按钮 ...
- 【LeetCode贪心#12】图解监控二叉树(正宗hard题,涉及贪心分析、二叉树遍历以及状态转移)
监控二叉树 力扣题目链接(opens new window) 给定一个二叉树,我们在树的节点上安装摄像头. 节点上的每个摄影头都可以监视其父对象.自身及其直接子对象. 计算监控树的所有节点所需的最小摄 ...
- Rancher 系列文章-K3s Traefik MiddleWare 报错-Failed to create middleware keys
概述 书接上回:<Rancher 系列文章-K3S 集群升级>, 我们提到:通过一键脚本升级 K3S 集群有报错. 接下来开始进行 Traefik 报错的分析和修复, 问题是: 所有 Tr ...
- 如何快速体验ChatGPT-4模型
OpenAI免费版基于Gpt3.5,无法使用最新发布的 GPT-4 模型,必须开通 ChatGPT Plus.但是 OpenAI 不但屏蔽了中国的 IP 地址,连国内的 Visa 信用卡也一同屏蔽,即 ...