【Redis】Redis的持久化机制(RDB快照和AOF日志实现原理)

Redis的持久化机制(RDB快照和AOF日志实现原理)

介绍

redis是一个基于内存的数据库,所以一旦发生宕机,数据将丢失,故而实现redis的持久化尤为重要。

redis持久化机制可以将内存中的数据保存到硬盘上,以便在需要时可以重新加载数据,从而确保数据不会因为服务器重启或其他异常情况而丢失。

redis的持久化机制有两种实现,RDB快照AOF日志

RDB快照

RDB介绍

RDB(Redis DataBase):把当前的进程的数据生成快照保存到磁盘。

RDB实现原理

RDB持久化机制有两种命令:

  • save:直接阻塞主进程,直到整个RDB过程完成,可能会造成长时间的阻塞。
  • bgsave:Redis进程执行fork操作创建子进程,RDB持久化过程由子 进程负责,完成后自动结束。阻塞只发生在fork阶段,一般时间很短。(主流)

RDB的写时拷贝(Copy-on-Write/COW)

在实际的生产环境中,我们给reids开辟的内存区域往往会比较大,所以当RDB数据持久化到硬盘的过程所耗费的时间会比较长,那么这个时间段内极有可能redis会收到新的写操作,RDB是如何如何保持数据的一致性的呢?

Redis 服务器会在触发 BGSAVE 时调用 redis Fork 函数来创建子进程并调用 rdbSave 在子进程中对数据进行持久化。在 fork 函数调用时,父进程和子进程会被 Kernel 分配到不同的虚拟内存空间中,所以在两个进程看来它们访问的是不同的内存,但是实际上它们的虚拟内存映射的是同一块物理内存,所以父子进程共享了物理上的内存空间,这相较于传统的fork时全量拷贝节省了巨大的开销。

而COW是指子进程在持久化到硬盘过程中读取物理内存的过程中,父进程发生了写操作,即父进程对共享的内存进行修改,这个时候共享的内存会以页为单位进行拷贝,父进程会保留原有的物理空间,而子进程会使用拷贝后的新物理空间。这也是redis在持久化过程中仍可以执行写操作的原因。

举例:假设在子进程持久化读取共享内存中的页时,父进程对某个页中的某个键值对(假设是键值对G)进行写操作,那么这个时候存放着键值对G的页将会拷贝一个副本,父进程依旧可以原始页进行写操作,子进程读取没有被写操作的副本页。

在这里插入图片描述

RDB的触发

RDB的触发方式有两种:

  • 手动触发,也就是上面说的save命令和bgsave命令。
  • 自动触发,通过配置和机制。
    • redis.conf中配置save m n,即在m秒内有n次修改时,自动触发bgsave生成rdb文件;
    • 主从复制时,从节点要从主节点进行全量复制时也会触发bgsave操作,生成当时的快照发送到从节点;
    • 执行debug reload命令重新加载redis时也会触发bgsave操作;
    • 默认情况下执行shutdown命令时,如果没有开启aof持久化,那么也会触发bgsave操作;

RDB相关配置

# 周期性执行条件的设置格式为
save <seconds> <changes>

# 每当满足其中一个条件时,Redis会自动触发RDB持久化操作:
save 900 1     # 在900秒(15分钟)之内,如果发生了至少1次修改
save 300 10    # 在300秒(5分钟)之内,如果发生了至少10次修改
save 60 10000  # 在60秒之内,如果发生了至少10000次修改

# 以下设置方式为关闭RDB快照功能
save ""

# 文件名称
dbfilename dump.rdb

# 文件保存路径
dir /home/work/app/redis/data/

# 如果持久化出错,主进程是否停止写入
stop-writes-on-bgsave-error yes

# 是否压缩
rdbcompression yes

# 导入时是否检查
rdbchecksum yes

AOF日志

介绍

AOF方式持久化是使用文本协议将每次的写命令记录到AOF文件中,经过文件重写后记录最终的数据生成命令,在redis启动时,通过执行AOF文件中的命令恢复数据。

AOF日志是写后日志,即在执行操作之后再记录日志,而mysql采用的是写前日志+二阶段提交。

AOF实现原理

AOF实现操作流程:命令写入 (append)、文件同步(sync)、文件重写(rewrite)、重启加载 (load)。

  • 命令写入 (append):在AOF持久化中,当有写操作(如SET、DEL等)发生时,Redis会将这个写操作记录下来并追加到AOF缓冲区中。
  • 文件同步(sync):AOF缓冲区中的数据不会立即写入AOF文件,而是根据持久化策略决定何时进行文件同步
  • 文件重写(rewrite):AOF文件在持续写入写操作后,可能会变得很大。为了压缩文件大小并提高性能,Redis可以执行AOF文件重写操作。
  • 重启加载 (load):当Redis服务器重启时,它会读取AOF文件中的命令,并按顺序执行这些命令,从而恢复数据集的状态。

AOF的文件重写

AOF为什么要进行文件重写?

AOF会记录每个写命令到AOF文件,随着时间越来越长,AOF文件会变得越来越大。如果不加以控制,会对Redis服务器,甚至对操作系统造成影响,而且AOF文件越大,数据恢复也越慢。所以出现了AOF文件重写,文件重写是一个后台操作,它会生成一个新的AOF文件,其中只包含能够重建数据集的命令。这样可以压缩AOF文件的大小。

在这里插入图片描述

为了防止重写过程中主进程阻塞,重写操作采用和RDB相似的策略。

在要进行重写操作时,主进程会fork一个子进程,来实现AOF重写操作,如果在重写的过程中,主进程正好出现了新的写操作,那么其也会采用COW策略来保证数据的一致性。文件重写通过bgrewriteaof命令来触发。

AOF相关配置

# appendonly参数开启AOF持久化,默认是关闭的
appendonly no

# AOF持久化的文件名,默认是appendonly.aof
appendfilename "appendonly.aof"

# AOF文件的保存位置和RDB文件的位置相同,都是通过dir参数设置的
dir ./

# 同步策略
# appendfsync always
appendfsync everysec
# appendfsync no

# aof重写期间是否同步
no-appendfsync-on-rewrite no

# 重写触发配置
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

# 加载aof出错如何处理
aof-load-truncated yes

# 文件重写策略
aof-rewrite-incremental-fsync yes

逐一解释一下相关参数:

  • appendonly:是否开启AOF(Append-Only File)持久化。如果设置为yes,则开启AOF持久化,将写操作追加到AOF文件中。
  • appendfilename:AOF文件的名称。AOF文件是用于保存写操作的文件。
  • dir:AOF文件的保存目录。与RDB文件的保存位置相同。
  • appendfsync:指定AOF文件何时进行同步操作,以保证数据的持久性。可选值:always、everysec、no。
    • always:每次写操作都会立即将缓冲区数据同步到AOF文件。
    • everysec:每隔一定时间(默认1秒),将缓冲区数据同步到AOF文件。
    • no:由操作系统决定何时将缓冲区数据同步到AOF文件。
  • no-appendfsync-on-rewrite:指定在AOF重写期间是否禁用同步操作。
  • auto-aof-rewrite-percentage:当AOF文件的大小超过上次重写时大小的一定百分比,自动触发AOF重写。默认为100,表示文件大小翻倍时触发。
  • auto-aof-rewrite-min-size:AOF重写的最小文件大小。如果AOF文件小于这个值,即使百分比条件满足,也不会触发重写。默认为64MB。
  • aof-load-truncated:当加载AOF文件时,如果文件被截断了,是否仍然加载剩余部分.
  • aof-rewrite-incremental-fsync:指定在AOF重写时是否增量同步文件。yes表示增量同步,可以提高写入性能,但也可能导致一些数据丢失的风险。

RDB和AOF混合

Redis 4.0 中提出了一个混合使用 AOF 日志和内存快照的方法。简单来说,内存快照以一定的频率执行,在两次快照之间,使用 AOF 日志记录这期间的所有命令操作。

这样一来,快照不用很频繁地执行,这就避免了频繁 fork 对主线程的影响。而且,AOF 日志也只用记录两次快照间的操作,也就是说,不需要记录所有操作了,因此,就不会出现文件过大的情况了,也可以避免重写开销。

在这里插入图片描述

该笔记更多是对redis持久化机制知识点的总结和浅整理,更深入的还需要去查看源码,该文章仅供参考,如果有问题或建议,十分欢迎探讨。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值