Redis 的持久化机制

在这里插入图片描述

1、为什么要持久化?

Redis 是基于内存操作的数据库,所有的数据都保存在内存中,而内存中的数据当程序结束时就会消失,所以我们要想办法把内存中的数据写到磁盘中,当程序正常退出或异常终止时,重新启动就可以从磁盘文件中恢复数据。Redis 有两种持久化机制,分别为 RDB(快照)和 AOF(日志)

2、RDB(Redis Database)

RDB(Redis Database)持久化策略,就是在符合一定条件下将内存所有的数据持久化到磁盘的 dump.rdb 文件中。RDB 文件是一个经过压缩的二进制文件,有多个部分组成,对于不同类型的键值对,RDB 文件会使用不同的方式来保存它们。RDB 策略是 Redis 默认的持久化策略,也叫快照策略

为什么叫快照策略?因为持久化到磁盘的数据是某一个时间点内存中所有的数据

2.1 触发机制

RDB 持久化触发机制分为手动触发自动触发

  • 手动触发
  1. save 命令:会阻塞当前服务器,直到 RDB 完成为止,在服务器进程阻塞期间,服务器不能处理任何网络请求。如果内存的数据量大的话会造成长时间的阻塞,线上环境一般禁止使用。
  2. bgsave 命令:(background save),执行 bgsave 命令时 redis 主进程会 fork 一个子进程来完成 RDB 的操作,子进程完成 RDB 任务后向父进程发送信号(操作系统的多进程 Copy On Write 机制,简称 COW)。所以 Redis 主进程阻塞的时间只有 fork 创建子进程那一下,相对于 save,阻塞的时间很短。

https://www.likecs.com/show-205096454.html?sc=400

命令savebgsave
IO 类型同步异步
是否阻塞是(阻塞发生在 fork 时,通常非常快)
复杂度O(n)O(n)
优点不会消耗额外的内存不阻塞客户端命令
缺点阻塞客户端命令需要 fork 子进程,消耗内存
  • 自动触发
  1. 配置 redis.conf 文件,根据触发规则自动触发 RDB
# 当在规定的时间内,Redis发生了写操作的个数满足条件,会触发发生BGSAVE命令。
# save <seconds> <changes>
# 当用户设置了多个save的选项配置,只要其中任一条满足,Redis都会触发一次BGSAVE操作
save 900 1          # 900秒之内至少一次写操作
save 300 10         # 300秒之内至少发生10次写操作
save 60 10000       # 60秒之内发生至少10000次写操作
  1. 执行 shutdown 命令关闭服务器,如果没有开启 AOF 持久化功能,那么会自动执行一次 bgsave
  2. 执行 flushall 命令

2.2 RDB 执行流程

Redis 使用操作系统的多进程 COW(Copy On Write)机制来实现 RDB 快照持久化

  1. 执行 bgsave 命令的时候,Redis 主进程会检查是否有子进程在执行 RDB/AOF 持久化任务,如果有的话,服务器拒绝执行此次的 bgsave 命令,直接返回;
  2. Redis 主进程会 fork 一个子进程来执行执行 RDB 操作,fork 操作会对主进程造成阻塞(影响 Redis 的读写),fork 操作完成后会发消息给主进程,从而不再阻塞主进程。(阻塞仅指主进程 fork 子进程的过程,后续子进程执行操作时不会阻塞);
  3. RDB 子进程会根据 Redis 主进程的内存生成临时的快照文件,持久化完成后会使用临时快照文件替换掉原来的 RDB 文件。(该过程中主进程的读写不受影响,但 Redis 的写操作不会同步到主进程的主内存中,而是会写到一个临时的内存区域作为一个副本
  4. 子进程完成 RDB 持久化后会发消息给主进程,通知 RDB 持久化完成(将上阶段内存副本中的增量写数据同步到主内存

Redis 的服务器周期性操作函数 serverCron 默认每隔 100 毫秒就会执行一次,该函数用于对正在运行的服务器的各类信息进行维护,它的其中一项工作就是检查 save 选项设置的保存条件是否已经满足,如果满足的话,就执行 BGSAVE 命令

2.3 优点

  • RDB 文件小,非常适合定时备份,用于灾难恢复;
  • Redis 加载 RDB 文件的速度比 AOF 快很多,因为 RDB 文件中直接存储的是内存数据,而 AOF 文件中存储的是一条条命令,需要重演命令。

2.4 缺点

  • RDB 无法做到实时持久化,若在两次 bgsave 间宕机,则会丢失区间(分钟级)的增量数据,不适用于实时性要求较高的场景
  • RDB 的 cow 机制中,fork 子进程属于重量级操作,频繁操作成本过高;
  • 存在老版本的 Redis 不兼容新版本 RDB 格式文件的问题。

3、AOF(Append Only File)

以日志的形式记录每一个写操作,将 Redis 执行过的所有命令都记录下来(读操作不记录)只许追加文件,但不可以改写文件, Redis 启动之初,会读取该文件,重构数据。也就是说,Redis 启动的时候把日志文件中的所有写操作再执行一遍,来恢复数据【当两种方式同时开启时,数据恢复 Redis 会优先选择AOF 恢复】

AOF 保存信息的文件的文件名为 appendonly.aof

3.1 开启方式

AOF 默认是关闭的,通过 redis.conf 配置文件进行开启

 ## 此选项为aof功能的开关,默认为“no”,可以通过“yes”来开启aof功能  
 ## 只有在“yes”下,aof重写/文件同步等特性才会生效  
 appendonly yes  
 
 ## 指定aof文件名称  
 appendfilename appendonly.aof  
 
 ## 指定aof操作中文件同步策略,有三个合法值:always everysec no,默认为everysec  
 appendfsync everysec  
 ## 在aof-rewrite期间,appendfsync是否暂缓文件同步,"no"表示“不暂缓”,“yes”表示“暂缓”,默认为“no”  
 no-appendfsync-on-rewrite no  
 
 ## aof文件rewrite触发的最小文件尺寸(mb,gb),只有大于此aof文件大于此尺寸是才会触发rewrite,默认“64mb”,建议“512mb”  
 auto-aof-rewrite-min-size 64mb  
 
 ## 相对于“上一次”rewrite,本次rewrite触发时aof文件应该增长的百分比  
 ## 每一次rewrite之后,redis都会记录下此时“新aof”文件的大小(例如A)
 ## aof文件增长到A*(1 + p)之后,触发下一次rewrite,每一次aof记录的添加,都会检测当前aof文件的尺寸。  
 auto-aof-rewrite-percentage 100

三种同步策略:

  • always:每一条 AOF 记录都立即同步到文件,性能很低,但较为安全。
  • everysec:每秒同步一次,性能和安全都比较中庸的方式,也是 Redis 推荐的方式。如果遇到物理服务器故障,可能导致最多 1 秒的 AOF 记录丢失。【推荐】
  • no:Redis 永不直接调用文件同步,而是让操作系统来决定何时同步磁盘。性能较好,但很不安全。

3.2 触发机制

和 RDB 类似,AOF 触发机制也分为:手动触发和自动触发

  • 手动触发
    直接调用 bgrewriteaof 命令
 redis-cli -h ip -p port bgrewriteaof
  • 自动触发
 (aof_current_size > auto-aof-rewrite-min-size ) && (aof_current_size - aof_base_size) / aof_base_size >= auto-aof-rewrite-percentage
 #其中aof_current_size和aof_base_size可以在info Persistence统计信息中查看。

3.3 AOF 重写

随着 Redis 的运行,被执行的写命令不断同步到 AOF 文件中,AOF 文件的体积越来越大,极端情况将会占满所有的硬盘空间。如果 AOF 文件体积过大,还原的过程也会相当耗时。为了解决 AOF 文件不断膨胀的问题,需要移除 AOF 文件中的冗余命令来重写 AOF。
 
AOF Rewrite 虽然是 “压缩” AOF 文件的过程,但并非采用 “基于原 AOF 文件” 来重写或压缩,而是采取了类似 RDB 快照的方式:基于 Copy On Write,全量遍历内存中数据,然后逐个序列化到 AOF 文件中。因此 AOF rewrite 能够正确反应当前内存数据的状态。Redis 提供了 bgrewriteaof 指令用于对 AOF 曰志进行瘦身,其原理就是开辟一个子进程对内存进行遍历,转换成一系列 Redis 的操作指令,序列化到一个新的 AOF 曰志文件中。序列化完毕后再将操作期间发生的增量 AOF 日志追加到这个新的 AOF日志文件中,追加完毕后就立即替代旧的 AOF 曰志文件了,瘦身工作就完成了。

3.4 优点

AOF 只是追加写日志文件,对服务器性能影响较小,速度比 RDB 要快,消耗的内存较少。

3.5 缺点

  • AOF 方式生成的日志文件太大,需要不断 AOF 重写,进行瘦身。
  • 即使经过 AOF 重写瘦身,由于文件是文本文件,文件体积较大(相比于 RDB 的二进制文件)。
  • AOF 重演命令式的恢复数据,速度显然比 RDB 要慢。

X、小结

  1. RDB 持久化方式能够在指定的时间间隔内对数据进行快照存储
  2. AOF 持久化方式记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据,AOF 追加保存每次写的操作到文件末尾,Redis 还能对 AOF 文件进行后台重写,使得 AOF 文件的体积不至于过大。
  3. 只做缓存,如果你只希望你的数据在服务器运行的时候存在,你也可以不使用任何持久化
  4. 同时开启两种持久化方式,在这种情况下,当 Redis 重启的时候会优先载入 AOF 文件来恢复原始的数据,因为在通常情况下 AOF 文件保存的数据集要比 RDB 文件保存的数据集要完整。RDB 的数据不实时,同时使用两者时服务器重启也只会找 AOF 文件。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值