Redis持久化策略:RDB 和 AOF

前言 

        Hello,大家好,我是Go。在现代应用程序的开发中,数据的稳定性和持久性是至关重要的。大多数应用选择将数据存储在内存中以提高性能,但一旦发生断电或及其故障,内存数据就会丢失。

        在这方面,Redis作为一种高性能的内存数据库,通过其持久化策略为我们提供了强大的解决方案。本文将探讨Redis的持久化策略,揭示其如何确保数据在内存中的稳固存储。


Redis持久化策略

        Redis ⽀持 RDBAOF 两种持久化机制,持久化功能有效地避免因进程退出造成数据丢失问题, 当下次重启时利⽤之前持久化的⽂件即可实现数据恢复。本文将介绍RDB和AOF的配置、运行流程和控制持久化的命令,带大家尽可能深入的了解这两种策略。

一、RDB(Redis Database)【定期备份】

        RDB持久化中,Redis会周期性地(根据配置的时间间隔)将内存中的数据快照保存到硬盘上的文件中。并且其触发的时机分为手动触发和自动触发。

手动触发分别对应 save 和 bgsave 命令:

  • save命令:阻塞当前的Redis服务器,直到RDB过程完成为止。当数据类过多时,会长时间阻塞Redis服务器,基本不采用
  • bgsave命令:Redis进程执行 fork 操作创建子进程,RDB持久化由子进程负责,完成后自动结束。只有在fork期间父进程才会阻塞,但时间非常短。

Redis内部所有涉及RDB的操作都采用类似bgsave的方式。

fork :此操作指创建一个子进程,该子进程复制父进程执行fork操作瞬间的所有数据。fork后父进程继续处理请求;子进程负责对数据进行RDB持久化

bgsave流程

  1. 执⾏ bgsave 命令,Redis ⽗进程判断当前进是否存在其他正在执⾏的⼦进程,如 RDB/AOF ⼦进 程,如果存在 bgsave 命令直接返回。
  2. ⽗进程执⾏ fork 创建⼦进程,fork 过程中⽗进程会阻塞。
  3. ⽗进程 fork 完成后,bgsave 命令返回 "Background saving started" 信息并不再阻塞⽗进程,可 以继续响应其他命令。
  4. ⼦进程创建 RDB ⽂件,根据⽗进程内存⽣成临时快照⽂件,完成后对原有⽂件进⾏原⼦替换。
  5. 进程发送信号给⽗进程表⽰完成,⽗进程更新统计信息。 

除了手动触发之外,Redis运行自动触发RDB持久化机制,这个触发机制才是实际中有价值的,常见的自动触发有:

1、使用save配置。如Redis的配置文件中,“save m n”表示 m 秒内发生了 n 次修改,自动化RDB持久化操作。这就决定了RDB持久化的定期备份。

2、从节点进行全量复制时,主节点自动进行RDB持久化,随后将RDB文件内容发给从节点。

3、执行shutdown命令关闭Redis时,执行RDB持久化

快照:相当于你出去旅游,只要看到美丽的景色,就掏出手机拍照记录,照片就记录了按下快门瞬间的风景的“全量数据

RDB文件的处理

保存:RDB ⽂件保存再 dir 配置指定的⽬录(默认 /var/lib/redis/)下,⽂件名通过 dbfilename 配置(默认 dump.rdb)指定。

校验:如果 Redis 启动时加载到损坏的 RDB ⽂件会拒绝启动。这时可以使⽤ Redis 提供的 redis-check-dump ⼯具检测 RDB ⽂件并获取对应的错误报告。

RDB文件优缺点

1、RDB 是⼀个紧凑压缩的⼆进制⽂件,代表 Redis 在某个时间点上的数据快照。⾮常适⽤于备份,全量复制等场景。⽐如每 6 ⼩时执⾏ bgsave 备份,并把 RDB ⽂件复制到远程机器或者⽂件系统中 (如 hdfs)⽤于灾备。

2、Redis 加载 RDB 恢复数据远远快于 AOF 的⽅式。

3、RDB ⽅式数据没办法做到实时持久化 / 秒级持久化。因为 bgsave 每次运⾏都要执⾏ fork 创建⼦进 程,属于重量级操作,频繁执⾏成本过⾼。

4、RDB ⽂件使⽤特定⼆进制格式保存,Redis 版本演进过程中有多个 RDB 版本,兼容性可能有⻛ 险。

5、定期备份过程中,短时间Redis处理大量数据,突发状况使Redis服务器崩溃,数据可能无法及时保存。


二、AOF(Append Only File)【实时备份】

        与RDB不同,AOF以独⽴⽇志的⽅式记录每次写命令,重启时再重新执⾏ AOF ⽂件中的命令达到恢复数据的⽬的。AOF 的主要作⽤是解决了数据持久化的实时性,⽬前已经是 Redis 持久化的主流⽅式。

        AOF保存的是数据的最终形态,例如当你 set key 1 后又修改了 key 为 2。那么最终AOF文件中保存的仅仅是 key 为 2,而少去了中间的修改命令的记录。 

开启AOF

开启 AOF 功能需要设置配置:appendonly yes,默认为 appendonly no。AOF ⽂件名通过 appendfilename 配置(默认是 appendonly.aof)设置。保存⽬录同 RDB 持久化⽅式⼀致,通过 dir 配置指定。

AOF工作流程

1、所有的写⼊命令会追加到 aof_buf(缓冲区)中。

AOF 命令写⼊的内容直接是⽂本协议格式。例如 set hello world 这条命令,在 AOF 缓冲区会追加如下 ⽂本:

*3\r\n$3\r\nset\r\n$5\r\nhello\r\n$5\r\nworld\r\n

AOF 过程中为什么需要 aof_buf 这个缓冲区?Redis 使⽤单线程响应命令,如果每次写 AOF ⽂件都直 接同步硬盘,性能从内存的读写变成 IO 读写,必然会下降。先写⼊缓冲区可以有效减少 IO 次数,同 时,Redis 还可以提供多种缓冲区同步策略,让⽤⼾根据⾃⼰的需求做出合理的平衡。

2、AOF 缓冲区根据对应的策略向硬盘做同步操作。

Redis 提供了多种 AOF 缓冲区同步⽂件策略,由参数 appendfsync 控制

always: 命令写⼊ aof_buf 后立即调⽤ fsync 同步,完成后返回。(操作频繁,性能差)

everysec(默认配置):命令写⼊aof_buf 后只执⾏ write 操作,不进⾏ fsync。每秒由同步线程进⾏ fsync。(兼顾性能和安全)

no:命令写⼊ aof_buf 后只执⾏ write 操作,由 OS 控制 fsync 频率。(安全性差,性能最高)

3、随着 AOF ⽂件越来越⼤,需要定期对 AOF ⽂件进⾏重写,达到压缩的⽬的。

4、当 Redis 服务器启动时,可以加载 AOF ⽂件进⾏数据恢复。

重写机制

        随着命令不断写⼊ AOF,⽂件会越来越⼤,为了解决这个问题,Redis 引⼊ AOF 重写机制压缩⽂件体积。AOF ⽂件重写是把 Redis 进程内的数据转化为写命令同步到新的 AOF ⽂件。重写机制使得AOF文件变小:

  • 进程内已超时的数据不再写⼊⽂件。
  • 旧的 AOF 中的⽆效命令,例如 del、hdel、srem 等重写后将会删除,只需要保留数据的最终版 本。
  • 多条写操作合并为⼀条,例如 lpush list a、lpush list b、lpush list 从可以合并为 lpush list a b c。

较⼩的 AOF ⽂件⼀⽅⾯降低了硬盘空间占⽤,⼀⽅⾯可以提升启动 Redis 时数据恢复的速度。

AOF 重写过程可以⼿动触发⾃动触发: 

手动触发:手动调⽤ bgrewriteaof 命令。

自动触发:根据 auto-aof-rewrite-min-size 和 auto-aof-rewrite-percentage 参数确定⾃动触发时 机。

        auto-aof-rewrite-min-size:表⽰触发重写时 AOF 的最⼩⽂件⼤⼩,默认为 64MB。

        auto-aof-rewrite-percentage:代表当前 AOF 占⽤⼤⼩相⽐较上次重写时增加的⽐例。

重写机制执行流程

 1、执⾏ AOF 重写请求。

  •         如果当前进程正在执⾏ AOF 重写,请求不执⾏。如果当前进程正在执⾏ bgsave 操作,重写命令 延迟到 bgsave 完成之后再执⾏。

2、⽗进程执⾏ fork 创建⼦进程。

3、重写

  •         主进程 fork 之后,继续响应其他命令。所有修改操作写⼊ AOF 缓冲区并根据 appendfsync 策 略同步到硬盘,保证旧 AOF ⽂件机制正确。
  •         ⼦进程只有 fork 之前的所有内存信息,⽗进程中需要将 fork 之后这段时间的修改操作写⼊ AOF 重写缓冲区中。

4、⼦进程根据内存快照,将命令合并到新的 AOF ⽂件中。

5、⼦进程完成重写

  •         新⽂件写⼊后,⼦进程发送信号给⽗进程。
  •         ⽗进程把 AOF重写缓冲区内临时保存的命令追加到新 AOF ⽂件中。
  •         ⽤新 AOF ⽂件替换⽼ AOF ⽂件,持久化存储完成

结语

        到此,对于RDB和AOF这两个持久化策略也就阐述完毕了。希望这些能够帮助大家,解决大家的问题。大家一起进步!笔者文章如有不足,欢迎随时指出!

        

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值