📃个人主页:island1314
⛺️ 欢迎关注:👍点赞 👂🏽留言 😍收藏 💞 💞 💞
- 生活总是不会一帆风顺,前进的道路也不会永远一马平川,如何面对挫折影响人生走向 – 《人民日报》
🔥 目录
一、引言
🔥 在学习 MySQL 数据库时,我们了解到事务的四个核心特性(ACID):原子性、一致性、持久性和隔离性。这些特性确保了数据库操作的安全性和可靠性。当我们转向 Redis 时,尽管它主要将数据存储在内存中,但为了保证数据的持久性,Redis 也提供了几种机制来 将数据保存到硬盘 上。
所谓持久化,就是能够把数据存储在硬盘上,这本身就是持久化,当数据存储在硬盘之后,当重启进程或是主机之后,数据也依旧存在。而我们知道Redis本身其实是一个内存级别的数据库,那这就意味着它本身其实是不能持久化的,要想让Redis实现持久化,就必须让Redis把数据写到硬盘上
那怎么写呢?
- 当现在要插入一个新的数据的时候,就需要把这个数据同时存储到磁盘和内存当中,而当查询某个具体的数据的时候,却还是依旧直接从内存中进行读取,硬盘中的数据只是为了在Redis进行重启的时候可以来恢复到内存中的数据的(用于重启恢复数据)
这样做是有代价的,同样的数据在硬盘和内存中都会进行存储,并且相对来说,一台电脑上硬盘是最容易坏的部分。
- CPU ==> 如果你把CPU用坏了,恭喜你,可以去买彩票了(bush
- 显卡 ==> 除非你是高强度挖矿(矿卡)
- “挖矿”是用电脑的算力去解复杂的数学问题,来获取虚拟货币的过程。
- 以 比特币 为例,它的交易记录保存在 区块链 中,“挖矿”就是矿工通过计算机运算来竞争记账权,成功就能获得比特币奖励。这一过程需要强大的计算能力,会消耗大量能源。
- “矿卡”是指用于挖矿的显卡。因为长时间高负荷工作,矿卡的使用寿命会缩短,性能也可能下降。和普通显卡相比,矿卡的硬件老化和损坏程度更严重。
- 内存 ==> 概率非常低
- 硬盘 ==>反而是最容易出问题的,尤其是“机械硬盘”(固态相对好些)
持久化到硬盘,有同学就会想,那硬盘坏了怎么办?对于重要资料,我们可以再拿另一块移动硬盘,来作为备份用的硬盘(毕竟其成本价格也不高)
持久化策略
当向 Redis 中插入数据时,需要同时考虑如何将数据写入内存和硬盘。为此,Redis 提现了两种不同的持久化策略:RDB(Redis Database)模式与 AOF(Append Only File)模式。
- RDB 模式:采取定期备份的方式,即每隔一段时间,就会把内存中的所有数据备份到硬盘上。这种方式适合用于冷备和主从复制场景。
- AOF 模式:采用实时备份的方法,每当内存中有新的数据变动时,都会立即追加记录到硬盘上的日志文件中。这种方法提供了更好的数据完整性保障,但在性能上可能不如 RDB 方式。
通过这两种方式,Redis 能够有效地平衡数据安全性和系统性能,让用户可以根据实际需求选择最合适的持久化方案。
二、RDB
1. 什么是 RDB 持久化?
定义:RDB 持久化 是指在指定的时间间隔内,将 Redis 内存中的数据集 写入磁盘文件,此时就生成了一个快照 (默认文件名:dump.rdb
),后续如果 [Redis 重启](https://so.csdn.net/so/search?q=Redis 重启&spm=1001.2101.3001.7020)了,也不用过多担心,可以根据之前的快照信息把数据存储起来进行恢复。这个过程也叫做“Snapshotting”。
特点:
- 快照式持久化;
- 文件紧凑,适合备份;
- 性能高(fork 子进程完成);
- 可能会丢失最后一次快照后的数据(取决于配置);
2. 触发机制
2.1 手动触发
程序员可以手动的进行存储快照,例如可以通过两个命令,save
或者是 bgsave
进行存储到本地
save
:在执行 save 命令的时候,Redis 会全力以赴的进行存储快照,这就意味着 Redis 会 阻塞其他请求,直到 RDB 文件创建完成。类似于之前说到的keys *
的问题(不推荐使用,因为会影响客户端请求)bgsave
:而对于 bgsave 来说,就解决了这个问题,而解决的方法其实采取的是使用了 多进程 的方式来进行解决的(Redis进程执行 fork操作创建子进程,RDB持久化过程由子进程负责,完成后自动结束。阻塞只发生在 fork 阶段)
bgsave 的运行流程
bgsave 是主流的 RDB 持久化方式,Redis 内部的所有涉及 RDB 的操作都采用类似 bgsave
的方式。
- 执行
bgsave
命令,Redis父进程判断当前进是否存在其他正在执行的子进程,如RDB/AOF子进程,如果存在bgsave
命令直接返回。 - 父进程执行
fork
创建子进程,fork过程中父进程会阻塞(注意:此时主进程可以继续处理客户请求,相当于后台异步执行 RDB 持久化) 。通过infostats
命令查看latest fork usec
选项,可以获取最近一次fork操作的耗时,单位为微秒。 - 父进程fork完成后,
bgsave
命令返回"Backgroundsavingstarted"
信息并 不再阻塞父进程,可以继续响应其他命令 - 子进程创建RDB文件,根据父进程内存生成 临时快照文件(dump.rdb),完成后对原有文件进行 原子替换。执行
lastsave
命令可以获取最后一次生成 RDB 的时间,对应 info 统计的rdblast save time
选项 - 进程发送信号给父进程表示完成,实现 新旧文件替换,父进程更新统计信息
注意:如果父进程在收到信号之前收到了另一个 bgsave
命令,它会直接返回而不处理,因为已经有子进程正在执行持久化操作。这样可以确保多个 bgsave
命令只触发一次持久化操作。
fork (写时拷贝)
其实执行 fork 时,父进程的所有资源(包括内存中的数据、进程地址空间、页表和 PCB 等)都会被复制一份给子进程,那么当前 Redis 服务器中存储的数据比较多, 内存消耗比较大,此时的复制操作是否会产生很大开销
- 此次的性能开销其实不大,因为 fork 在进行内存拷贝的时候,不是直接简单无脑的拷贝所有数据,而是采用 写时拷贝 的机制来完成。
- 如果子进程里面的内存数据 和 父进程的内存数据完全一样,就不会触发真正的拷贝动作(因为这样就相当于共用一份内存数据),但是它两的内存空间应该是相互独立的,一旦某一方针针对数据作出修改就会真正触发真正的物理内存上的数据拷贝
关于 写时复制(Copy-onWrite,COW)机制,请分析一下其是如何工作的?
- 当 BGSAVE 开始时,Redis会 fork 一个子进程。
- 在fork操作之后,父进程(即主进程)和子进程都会有一份数据页的副本。但是,这些页在物理内存中是共享的,而不是立即复制。
- 如果父进程接收到写操作,它会在写入之前复制受影响的页,这样子进程中的数据页仍然是执行 BGSAVE 命令那一刻的快照状态。
- 子进程在创建RDB文件时,会使用这些未被修改的数据页。如果数据页在子进程创建RDB文件期间被修改了,子进程会使用其创建时那一刻的页副本。
通过这种方式,Redis能够在不阻塞主进程的情况下保存数据快照,同时保证了数据的一致性。需要注意的是,写时复制机制会导致额外的内存使用,因为修改的数据页会被复制。如果写操作非常频繁,这可能会对性能产生一定的影响。
小结:
bgsave
命令:通过fork
创建子进程来生成数据快照,父进程继续响应其他命令。- 写时拷贝:
fork
时并不立即复制所有内存数据,而是采用 写时拷贝(Copy-on-Write, COW) 技术,只有在实际写入时才进行拷贝,从而提高效率并节省内存空间。
新旧文件替换
注意:rdb 的持久化操作是可以多次触发的(原子替换)
- 当执行生成 rdb 镜像操作的时候,此时就会把要生成的快照数据先保存到一个临时文件中
- 当这个快照生成完毕之后,再删除之前的 rdb 文件,把新生成的临时的 rdb 文件名字改成 dump.rdb
🚀 关于文件是否被替换,我们可以使用Linux的 stat
命令来查看文件的 iNode
(文件系统索引节点) 编号。在执行bgsave命令之后,我们发现文件的 iNode
有变化.
可以发现 bgsave 后,inode 发生了变化,说明 存在 子进程 & 新旧文件替换。而 save命令是直接在之前的旧文件上写入数据, 所以在执行save命令之后, dump.rdb文件的iNode不会改变
2.2 自动触发
除了手动触发之外,Redis 运行自动触发 RDB 持久化机制,这个触发机制才是在实战中有价值的,以下是三种主要的“自动触发机制”
① 根据 save 配置规则触发(最常见)
对于 RDB 来说,它并不是随时都会进行更新的,而是需要一定的触发时机,RDB快照的生成是定期生成,所以我们可以在Redis的配置文件中设置让Redis每隔多长时间就触发一次.其中的配置项是save
配置项.
可以 cd /ect/redis
中 vim redis.conf
查看到
-
配置格式:
save <seconds> <changes>
,表示在指定秒数内发生了指定次数的写操作,就自动执行一次 BGSAVE -
在这个配置文件中,可以看到当前 Redis 的持久化策略是,900 秒内改变1次就进行缓存,300 秒内改变 10 次,60 秒内改变 10000 次…以此类推。当我们把save配置项设置为一个 空字符串(“”)的时候或者注释删除掉,这时候就会关闭快照的定期自动生成.
②主从复制时,主节点自动进行 RDB 持久化
🔄 当一个从节点(slave)第一次连接到主节点(master)并请求全量复制(Full Resynchronization)时,主节点会自动执行以下流程:
- 执行
BGSAVE
生成 RDB 快照; - 子进程将快照写入临时文件;
- 主进程将该 RDB 文件发送给从节点;
- 从节点加载 RDB 文件以初始化自己的数据集;
- 后续使用 AOF 或增量同步保持一致。
主从复制时,主节点为什么需要生成 RDB 文件?
- 为了将当前完整数据集发送给从节点进行初始化同步
③ 关闭 Redis 服务器时自动触发 RDB
当你执行如下命令关闭 Redis 服务时:redis-cli shutdown
,此时Redis 会:
- 如果开启了 RDB 持久化功能,自动执行一次
BGSAVE
; - 等待 RDB 文件写入完成后,安全退出;
- 保证最后一次内存数据被保存下来。
shutdown 命令为什么会触发 RDB?
- 为了防止数据丢失,Redis 在退出前默认保存一次数据
❗ 特别注意:如果你使用的是
shutdown nosave
命令,则不会触发 RDB 持久化 。
2.3 具体操作
① 手动执行 save & bgsave 触发一次生成快照
127.0.0.1:6379> set key1 111
OK
127.0.0.1:6379> bgsave
Background saving started
-
由于咱们这里的数据比较少,执行 bgsave 瞬间就完成了,立即査看应该就是有结果的。如果以后咱们接触到的数据多了,执行 bgsave 就可能需要消耗一定的时间。立即查看不一定就是生成完毕了~~
-
通过上述的操作,就可以看到redis 服务器在重新启动的时候,加载了 rdb 文件的内容恢复了内存中之前的状态了
② 插入新的 key ,不手动执行 bgsave,重新启动 redis 服务器
- 刚刚虽然没有执行 bgsave,但是这个 key 仍然重启后仍然存在
- 如果是通过正常流程重新启动 redis 服务器,此时 redis 服务器会在退出的时候,自动触发生成 rdb 操作但是如果是异常重启(kill -9 或者 服务器掉电),此时 redis 服务器来不及生成 rdb,内存中尚未保存到快照中的数据,就会随着重启而丢失
3. RDB 文件处理
Redis 生成的 rdb 文件是存放在 redis 的工作目录,也就是在 redis 配置文件设置的,如下:
root@VM-8-10-ubuntu:/var/lib/redis# pwd
/var/lib/redis
root@VM-8-10-ubuntu:/var/lib/redis# ll
total 16
drwxr-x--- 2 redis redis 4096 Jun 1 23:45 ./
drwxr-xr-x 50 root root 4096 Jun 1 21:09 ../
-rw-rw---- 1 redis redis 93 Jun 1 23:45 backup.db
-rw-rw---- 1 redis redis 109 Jun 1 21:55 dump.rdb # rdb 机制生成的镜像文件, 二进制文件把内存数据压缩保存, 节省空间
#redis 提供了 rdb 的检查工具
root@VM-8-10-ubuntu:/usr/bin# ll redis-*
-rwxr-xr-x 1 root root 748200 Mar 4 2022 redis-benchmark*
-rwxr-xr-x 1 root root 1474504 Mar 4 2022 redis-check-aof*
-rwxr-xr-x 1 root root 1474504 Mar 4 2022 redis-check-rdb*
-rwxr-xr-x 1 root root 362632 Mar 4 2022 redis-cli*
lrwxrwxrwx 1 root root 15 Mar 4 2022 redis-server -> redis-check-rdb*
-
保存:RDB 文件保存在 dir 配置指定的目录(默认
/var/lib/redis/
)下,文件名通过dbfilename
配置(默认dump.rdb
)指定。可以通过执行configsetdir{newDir}
和configsetdbfilename{newFilename}
运行期间动态执行,当下次运行时RDB文件会保存到新目录 -
压缩:Redis默认采用 LZF算法 对生成的RDB文件做压缩处理(二进制文件),压缩后的文件远远小于内存大小,默认开启,可以通过参数
configsetrdbcompression{yes|no}
动态修改- 虽然压缩 RDB 会消耗CPU,但是可以大幅降低文件体积,方便保存到硬盘或通过网络发生到 从节点,建议开启
- 由于RDB文件直接关系到Redis的数据持久化,因此不建议随意修改该文件。如果文件损坏,Redis可能无法正常启动,或者即使启动成功,数据也可能与预期不符(!!!重要性)
-
校验:如果Redis启动时加载到损坏的RDB文件会拒绝启动。这时可以使用 Redis 提供的
redischeck-dump
工具检测 RDB 文件并获取对应的错误报告root@VM-8-10-ubuntu:/usr/bin# redis-check-rdb /var/lib/redis/dump.rdb [offset 0] Checking RDB file /var/lib/redis/dump.rdb [offset 27] AUX FIELD redis-ver = '6.0.16' [offset 41] AUX FIELD redis-bits = '64' [offset 53] AUX FIELD ctime = '1748786147' [offset 68] AUX FIELD used-mem = '809768' [offset 84] AUX FIELD aof-preamble = '0' [offset 86] Selecting DB ID 0 [offset 109] Checksum OK [offset 109] \o/ RDB looks OK! \o/ [info] 1 keys read [info] 0 expires [info] 0 already expired
-
日志检查:当 Redis 服务器启动失败时,可以通过查看 Redis 日志来了解具体原因。
- 日志文件通常位于 /var/log/redis/ 目录下,可以通过以下命令查看:
cd /var/log/redis/
- 日志文件通常位于 /var/log/redis/ 目录下,可以通过以下命令查看:
关于RDB 文件结构
RDB 文件是一个二进制压缩文件,主要包括以下几个部分:
部分 | 描述 |
---|---|
文件头 | 标识 RDB 文件格式版本等信息 |
数据库信息 | 包含数据库编号、键值对数量等 |
键值对 | 实际存储的 key 和 value |
结尾 | 标识 RDB 文件结束 |
校验码 | CRC64 校验码,用于校验完整性 |
正确配置和管理 RDB快照对于保证Redis数据的安全性和一致性至关重要。同时,合理设置快照生成频率,既能避免过多消耗系统资源,又能有效减少因服务异常导致的数据损失风险。
4. RDB 优缺点
优点:
- 文件紧凑,便于备份和传输:RDB是⼀个紧凑压缩的二进制文件,代表Redis在某个时间点上的数据快照,便于备份、传输
- 例如:每6小时执行
bgsave
备份,并把RDB 文件复制到远程机器或者文件系统 (如 hdfs)
- 例如:每6小时执行
- 适合灾难恢复、恢复速度快:用于灾备Redis加载RDB恢复数据远远快于AOF的方式
- 性能好、不影响主进程:后台异步执行 RDB 持久化
缺点:
- 容易丢失最近一次快照后的数据
- 大数据集 fork 子进程可能耗时:RDB 方式数据没办法做到实时持久化 / 秒级持久化,因为bgsave每次运行都要执行 fork创建子进程,属于重量级操作,频繁执行成本过高
- 兼容性差:RDB 文件使用特定⼆进制格式保存,Redis 版本演进过程中有多个 RDB 版本,兼容性可能有风险
- RDB 文件不可读,无法直接查看内容, 对实时性要求高的场景不适用
适合场景:容灾备份、快速恢复、低频写入系统
🧑💻 Redis 生成 RDB 快照这件事,本身是一件成本比较高的事,所以生成快照不可以太频繁,而因为生成快照不能太频繁,就意味着可能会出现快照数据和实际数据相差较大的情况
那为了解决这样的问题,就出现了 AOF 这种解决方案
三、AOF
AOF(Append Only File)是 Redis 提供的另一种持久化机制 ,以独立日志的方式记录所有写操作命令,Redis 重启时再重新执行AOF文件中的命令来恢复数据。
- AOF的主要作用是解决了数据持久化的 实时性 问题,目前已经是Redis持久化的主流方式
- AOF 作为一种解决方案,对标的是 RDB 这种解决方案,RDB 带来的问题是:不能进行实时的持久化保存数据,在两次生成快照之间,实时的数据就会因为重启而丢失
- 因此有了 AOF,AOF 策略有些类似于
binlog
,它会把用户的每一个操作都记录在文件当中,这样当 Redis 进行重新启动的时候,就会读取这个 AOF 中的内容,来进行恢复数据
1. AOF 使用
AOF文件是一个 文本文件,每次进行的操作都会被记录到这个文本文件中,通过一些特殊符号作为分隔符来对命令的细节做出区分,而且一般默认是 关闭状态,我们需要通过修改配置文件来开启AOF功能,当开启 AOF 的时候,RDB 就不生效了.
重启Redis服务之后生效.(配置 redis.conf)
-
文件名配置:通过
appendfilename
配置项(默认是appendonly.aof
)来指定AOF文件名。 -
保存目录:与RDB持久化方式一致,通过
dir
配置指定。
重启后测试结果:
AOF 工作流程
- 命令写入(append):所有写入命令追加到
aof_buf
(缓冲区)中。 - 文件同步(sync):根据配置的策略向硬盘同步AOF缓冲区内容。
- 文件重写(rewrite):定期对AOF文件进行重写以压缩其体积。
- 重启加载(load):Redis 启动时加载AOF文件恢复数据。
1.2 AOF 文件结构
AOF 文件是纯文本格式的,记录的是 Redis 客户端发送的原始协议命令。例如set hello world
这条命令,在AOF缓冲区会追加如下文本:
*2\r\n$6\r\nSELECT\r\n$1\r\n0\r\n
*3\r\n$3\r\nSET\r\n$3\r\nkey\r\n$5\r\nvalue\r\n
对应 Redis 客户端请求协议(RESP),表示:
- 选择数据库 0;
- 设置 key 为 “value”;
Redis选择文本协议的原因包括兼容性、实现简单和具备可读性。使用
aof_buf
这个缓冲区,使AOF机制在备份数据的时候,不是直接让工作线程写入硬盘,而是先写入一个内存中的缓存区,积累一波之后,再统一写入硬盘.可以有效减少IO次数,并允许用户根据需求选择不同的同步策略,从而在性能和安全性之间做出平衡。
2. 文件同步
Redis 虽然是一个单线程的服务器,但是速度依旧很快,快的原因在于只是进行 操作内存,那引入AOF 后,又要进行内存操作也要进行磁盘读取,是否会影响效率? ==> 答案是否定的
- AOF 的机制并非让工作线程直接进行磁盘的操作,而是把信息存储到缓冲区后,然后把信息统一写入硬盘
- AOF每次把新的操作写入到原有文件的末尾,属于顺序写入。这个效率是比 随机写入 快的,从某种程度上来说也是一种解决的方式。
正是由于上面的两点,使得AOF虽然既要写内存又要写硬盘,但是他的效率没有降低多少.
那有个问题:如果把数据写在缓冲区的时候(由于本质上还是写在缓存中的),如果突然掉电 或 进程崩溃,此时缓冲区的数据就会丢失,同时 Redis 也会数据丢失。
- 因此给出的解决方式是 Redis 提供了选项,可以允许程序员进行实际情况来判断缓冲区的刷新策略,频率越高,就意味着性能影响越大,数据可靠性越高,反之也是这样(更新缓冲区数据的频率选项)
Redis提供了多种AOF缓冲区同步文件策略,由参数 appendfsync
控制,不同值的含义如下所示
可配置值 | 说明 |
---|---|
always | 命令写入aof_buf 后立即调用fsync 同步 |
everysec | 每秒由后台线程调用fsync 同步 |
no | 不主动调用fsync ,依赖操作系统 |
系统调用write和fsync的区别在于:write操作触发延迟写机制,而 fsync
强制同步到磁盘。
- write 操作会触发延迟写(delayedwrite)机制。Linux在内核提供页缓冲区用来提供硬盘IO性能。write操作在写入系统缓冲区后立即返回。同步硬盘操作依赖于系统调度机制,例如:缓冲区页空间写满或达到特定时间周期。同步文件之前,如果此时系统故障宕机,缓冲区内数据将丢失。
- Fsync 针对单个文件操作,做强制硬盘同步,fsync将阻塞直到数据写⼊到硬盘。
刷新频率越高,性能影响越大,同时数据的可靠性越高,刷新频率越低,性能影响越小,数据的可靠性越低.
- always配置虽然最安全但性能差
- no配置提高了性能但增加了数据丢失的风险;
- everysec是默认且推荐的配置,它能在数据安全性和性能间取得较好的平衡。
缓冲区刷新率也可以在配置文件中进行配置,具体的配置项是 appendfsync ,程序员可以根据自己的需要进行更改.
3. 重写机制
随着AOF(Append Only File)文件体积的持续增长,文件会越来越大,这会影响到Redis下次启动时的启动时间。
- 因为Redis在启动时需要读取AOF文件的内容,而AOF记录的是操作Redis的中间过程。
- 实际上,Redis重启时关注的是 最终的数据状态。
- 为了优化这一过程,AOF可以通过 剔除冗余操作 和 合并操作 来减少文件大小,这就是AOF的重写机制。
重写后的AOF为什么可以变小?有如下原因:
- 进程内已超时的数据不再写入文件。
- 旧的AOF中的无效命令,例如del、hdel、srem等重写后将会删除,只需要保留数据的最终版本。
- 多条写操作合并为一条,例如lpushlista、lpushlistb、lpushlist从可以合并为 lpushlistabc.
示例1:
- 原始操作:lpush key 111 和 lpush key 222
- 优化后:lpush key 111 222
示例2:
- 原始操作:set key 111 和 set key 222
- 优化后:只保留最后一个设置操作 set key 222
AOF 重写过程包含以下 触发条件:
- 手动触发:可以调用
bgrewriteaof
指令来触发AOF重写 - 自动触发:依据配置参数
auto-aof-rewrite-min-size
和auto-aof-rewrite-percentage
确定自动触发时机,前者表示AOF文件相对于上次重写时 增加的比例,后者表示触发 重写的最小文件大小
AOF 重写流程
1)执行 AOF 重写请求:如果当前进程正在执行 AOF 重写,请求不执行。如果当前进程正在执行 bgsave
操作,重写命令延迟到bgsave完成之后再执行
2)子进程创建与数据获取:
- 父进程通过fork创建一个子进程。
- 子进程不关心旧AOF文件内容,仅基于内存中的当前数据状态生成新的AOF文件。
3)重写
父子进程协作:
- 父进程fork 之后继续接收命令,并将这些命令写入 AOF 缓冲区,并根据
appendfsync
策略同步到硬盘,确保即使重写失败也能保持数据完整性。父进程继续处理客户端请求,所有新的写操作会被记录到两个地方:- 原来的 AOF 缓冲区(
server.aof_buf
) ➜ 最终刷盘到旧 AOF 文件; - AOF 重写缓冲区(
server.aof_rewrite_buf_blocks
) ➜ 后续追加到新 AOF 文件;
- 原来的 AOF 缓冲区(
- 在子进程完成新AOF文件的写入后,它会通知父进程。
- 父进程将 fork以来收到的新命令从
aof_rewrite_buf
缓冲区追加到新AOF文件中 - 替换旧的 AOF 文件
- 清空 AOF 重写缓冲区
- 父进程将 fork以来收到的新命令从
问题:父进程在fork之后继续写旧 AOF 的意义
-
问题描述:在Redis中进行AOF(Append Only File)文件重写时,父进程在fork子进程之后,子进程开始写入新的AOF文件。随着时间推移,子进程很快会完成新AOF文件的写入。此时,父进程继续写入即将被替换的旧AOF文件是否还有必要?
-
回答:有必要。我们需要考虑 极端情况,比如在AOF文件重写过程中,如果子进程或服务器意外挂掉,子进程的内存数据将丢失,导致新的AOF文件不完整。因此,父进程会继续写入旧的AOF文件,以确保数据的安全性。
四、RDB 和 AOF区别
- RDB以 二进制 的方式来组织数据,直接把数据读取到内存中,按照字节的格式取出来,放到结构体/对象中即可
- AOF使用 文本 的方式来组织数据,需要进行一系列的字符串切分操作
问题:执行BGREWRITEAOF时的特殊情况处理
问题描述:
- 如果在执行BGREWRITEAOF命令时,Redis已经在进行AOF重写,会发生什么?
- 如果在执行BGREWRITEAOF命令时,Redis正在生成RDB快照文件,会发生什么?
回答:
- 如果Redis已经在进行AOF重写,那么执行
BGREWRITEAOF
命令时,不会再次进行AOF重写,系统会直接返回。 - 如果Redis正在生成RDB快照文件,执行
BGREWRITEAOF
命令时,AOF重写操作会等待,直到RDB快照生成完成后,再进行AOF重写。
优先级:如果Redis上同时存在AOF文件和RDB快照的时候,此时以AOF文件为主,RDB直接被忽略.
混合持久化
为了解决纯文本写入的成本问题,Redis引入了混合持久化模式,结合了RDB和AOF的优点。
通过配置项aof-use-rdb-preamble激活此功能后,Redis会在AOF重写时先以RDB二进制格式保存当前内存状态,之后的操作则继续以AOF文本格式追加到文件后面,重写时为 RDB 格式。
这种策略减少了写入成本,同时保持了AOF的实时性。
持久化 sum
Redis提供了两种持久化方案:RDB和AOF。
- RDB视为内存快照,产生的内容紧凑,恢复速度快,但不适合实时持久化,通常用于冷备和主从复制。
- AOF视为修改命令的保存,并通过 重写机制定期压缩AOF文件。
- RDB和AOF都利用Linux 子进程拥有父进程 内存快照 的特点进行持久化,尽量不影响主进程处理命令。
【★,°:.☆( ̄▽ ̄)/$:.°★ 】那么本篇到此就结束啦,如果有不懂 和 发现问题的小伙伴可以在评论区说出来哦,同时我还会继续更新关于【Redis】的内容,请持续关注我 !!