【Redis】redis持久化

redis 持久化

Redis是内存数据库,数据都是存储在内存中,为了避免进程退出导致数据的永久丢失,需要定期将Redis中的数据以某种形式(数据或命令)从内存保存到硬盘;当下次Redis重启时,利用持久化文件实现数据恢复。除此之外,为了进行灾难备份,可以将持久化文件拷贝到一个远程位置。# 持久化的方式

快照方式

快照是某时某刻对数据的完整备份。在以下数据持久化时被使用:

  • MySQL Dump
  • Redis RDB

日志

数据库做任何操作的更新就将它记录在日志中,当某时刻需要将数据恢复的时候,只需要将日志中的操作重新执行一遍,便得到某时某点的完整数据。在以下数据持久化时被使用:

  • MySQL Binlog
  • Hbase HLog
  • Redis AOF

redis持久化方式

RDB

经过RDB之后,redis会将内存中的数据创建一份快照到硬盘中,称为RDB文件(二进制,直接查看是乱码)。当redis重新启动时,会加载硬盘中的RDB文件,加载到内存中完成数据恢复。
在这里插入图片描述

RDB 的触发方式 - 主要三种方式

  • save(同步–命令)
  • bgsave(异步–命令)
  • 自动(配置文件中设置)

save(同步)
执行流程如下:
在这里插入图片描述

  • 在 save 的同时,其他命令会阻塞等待
  • 如果存在老的 RDB 文件,会先创建一个临时文件,然后对老文件进行替换
  • 时间复杂度,O(n)

bgsave(异步)
执行流程如下:
在这里插入图片描述

  • 调用 bgsave 后,会调用 linux 的 fork() 函数,创建一个子进程
  • 如果存在老的 RDB 文件,会先创建一个临时文件,然后对老文件进行替换
  • 时间复杂度,O(n)
  • 子进程名称:redis-rdb-bgsave

自动方式

  • 内部相当于bgsave
  • Redis(6.2.6版本)默认的save配置如下表:
配置secondchanges
save36001
save300100
save6010000

满足以上任一条件,将创建(bgsave)RDB 文件(二进制)。比如 60秒内,有10000 条数据发生改变,将自动生成 RDB 文件。此方式的优点是生成的二进制文件是紧凑型的,可按需备份,而且通过RDB恢复数据的速度远远快于AOF。缺点是不好控制 RDB 文件的生成,如果写入量很大的话 RDB 生成太过频繁,频繁写入硬盘,对硬盘负担很大;无法实时持久化(bgsave每次都要fork建立子进程,属于重量级操作),且生成的文件是二进制文件,新旧版本可能存在不兼容的情况。

RDB 相关配置

配置项默认值含义
dbfilenamedump.rdbRDB快照文件名
dir./RDB快照文件生成所在目录
stop-writes-on-bgsave-erroryesbgsave时发生错误是否停止写入
rdbcompressionyesRDB文件是否采用压缩
rdbchecksumyes是否对RDB进行校验

RDB 最佳配置

  • 不配置自动RDB操作
  • dbfilename dump-${port}.rdb
  • dir /redisDataPath
  • stop-writes-on-bgsave-error yes
  • rdbcompression yes
  • rdbchecksum yes

触发机制

以下几种情况会触发生成快照:

  • 客户端执行命令save和bgsave时会生成快照
  • 根据配置文件save m n规则进行自动快照
  • 主从复制时从节点执行全量复制,master 节点会执行 bgsave并将RDB文件发给从节点
  • debug reload命令重新加载redis
  • 默认执行shutdown时,如果没有开启AOF,则自动执行bgsave
  • 客户端执行shutdown关闭redis时,触发快照

AOF

通过日志方式将redis中的写命令进行日志记录,保存在硬盘文件中。日志记录的实质是将写命令写在硬盘的缓冲区中,再根据相关策略把数据刷新到磁盘中。当redis服务器启动时候,执行硬盘中的日志文件以恢复redis中的数据。如果日志文件很大(数据量大),恢复速度可能比较慢。

AOF 运行原理 - 创建
在这里插入图片描述
AOF 运行原理 - 恢复
在这里插入图片描述

AOF 的三种刷新策略

策略含义
always执行每条写命令都会将写命令写到磁盘中
everysec每秒将数据从缓冲区刷到磁盘中,可能会丢失一秒的数据(redis 默认使用该策略)
no写命令何时刷新的磁盘中,由操作系统来决定

AOF 重写

注意这里的重写并不是说将 redis 命令重新抽象成新的 redis 命令,再写入 AOF 文件,而是执行 redis 命令后将内存中的数据进行回溯,重写成 AOF 文件。

  • 重写的作用:减少磁盘占用(过期的数据不再写入文件,无效的命令不再写入文件)、加速AOF恢复速度(命令合并)
    例如一千次incr key 可以重写为 set key 1000
  • AOF 重写实现方式 - bgrewriteaof
    客户端发送出一条bgrewriteaof命令后,redis会fork一个子进程完成AOF重写操作逻辑。

AOP 重写实现方式 - AOF 重写配置

  • AOF配置项
配置默认值含义
auto-aof-rewrite-min-size64MBAOF文件重写需要的尺寸,AOF多大时开启重写
auto-aof-rewrite-percentage100AOF文件增长率(当前AOF文件大小超过上一次重写的AOF文件大小的百分之多少才会重写)
  • AOF统计项
统计名含义
aof_current_sizeAOF当前尺寸(单位:字节)
aof_base_sizeAOF上次启动和重写的尺寸(单位:字节)
  • 自动触发时机
    • 当前 AOF 文件大小超过最小重写尺寸
    • 当前 AOF 文件大小超过上次重写完的 AOF 尺寸的百分之多少(auto-aof-rewrite-percentage)
aof_current_size > auto-aof-rewrite-min-size
(aof_current_size - aof_base_size) / aof_base_size > auto-aof-rewrite-percentage 

AOF 相关配置

配置项最佳取值含义
appendonlyyes开启AOF
appendfilenameaof-${port}.aofAOF文件名
appendfsync everysecAOF策略
dir/redisDataPathAOF文件所在目录
no-appendfsync-no-rewriteyes在执行重写时不进行AOF操作
auto-aof-rewrite-percentage100AOF重写配置(见上文)
auto-aof-rewrite-min-size64MBAOF重写配置(见上文)

AOF 重写原理

AOF 重写流程示意图如下:
在这里插入图片描述
说明:

  • bgrewriteaof触发重写,判断是否当前有bgsave或bgrewriteaof在运行,如果有,则等待该命令结束后再继续执行。
  • 主进程fork出子进程执行重写操作,保证主进程不会阻塞。
  • 子进程遍历redis内存中数据到临时文件,客户端的写请求继续写入aof_buf 缓冲区和aof_rewrite_buf重写缓冲区保证原AOF文件完整以及新AOF文件生成期间的新的数据修改动作不会丢失。
  • 子进程写完新的AOF文件后,向主进程发信号,父进程更新统计信息。 主进程把aof_rewrite_buf中的数据写入到新的AOF文件。
  • 使用新的AOF文件覆盖旧的AOF文件,完成AOF重写。

RDB-AOF混合持久化

在redis4.0版本中,相对与之前的版本其中一个比较大的变化是4.0添加了新的混合持久化方式。所谓的混合持久化就是同时结合RDB持久化以及AOF持久化混合写入AOF文件。这样做的好处是可以结合 rdb 和 aof 的优点, 快速加载同时避免丢失过多的数据,缺点是 aof 里面的 rdb 部分就是压缩格式不再是 aof 格式,可读性差。

开启混合持久化

在6.0版本的redis中混合持久化默认关闭的,通过aof-use-rdb-preamble配置参数控制,yes则表示开启,no表示禁用,默认是禁用的,可通过config set修改。

混合持久化过程

混合持久化同样也是通过bgrewriteaof完成的,不同的是当开启混合持久化时,fork出的子进程先将共享的内存副本全量的以RDB方式写入aof文件,然后在将重写缓冲区的增量命令以AOF方式写入到文件,写入完成后通知主进程更新统计信息,并将新的含有RDB格式和AOF格式的AOF文件替换旧的的AOF文件。简单的说:新的AOF文件前半段是RDB格式的全量数据后半段是AOF格式的增量数据。

数据恢复

当我们开启了混合持久化时,启动redis依然优先加载aof文件,aof文件加载可能有两种情况如下:

  • aof文件开头是rdb的格式, 先加载 rdb内容再加载剩余的 aof。
  • aof文件开头不是rdb的格式,直接以aof格式加载整个文件。
127.0.0.1:6379> DBSIZE
(integer) 7
127.0.0.1:6379> CONFIG sET aof-use-rdb-preamble yes
OK
127.0.0.1:6379> BGREWRITEAOF
Background append only file rewriting starte

退出查看,或者另一个终端查看aof文件
在这里插入图片描述
也可以通过redis自带的检查命令去检查一下持久化文件是否正确。

[root@k8s-m2 redis]# ./src/redis-check-rdb dump.rdb 
[offset 0] Checking RDB file dump.rdb
[offset 26] AUX FIELD redis-ver = '6.2.6'
[offset 40] AUX FIELD redis-bits = '64'
[offset 52] AUX FIELD ctime = '1704348988'
[offset 67] AUX FIELD used-mem = '831144'
[offset 83] AUX FIELD aof-preamble = '0'
[offset 85] Selecting DB ID 0
[offset 107] Checksum OK
[offset 107] \o/ RDB looks OK! \o/
[info] 2 keys read
[info] 0 expires
[info] 0 already expired
[root@k8s-m2 redis]# ./src/redis-check-aof /appendonly.aof 
The AOF appears to start with an RDB preamble.
Checking the RDB preamble to start:
[offset 0] Checking RDB file /appendonly.aof
[offset 26] AUX FIELD redis-ver = '6.2.6'
[offset 40] AUX FIELD redis-bits = '64'
[offset 52] AUX FIELD ctime = '1709537259'
[offset 67] AUX FIELD used-mem = '872648'
[offset 83] AUX FIELD aof-preamble = '1'
[offset 85] Selecting DB ID 0
[offset 132] Checksum OK
[offset 132] \o/ RDB looks OK! \o/
[info] 7 keys read
[info] 0 expires
[info] 0 already expired
RDB preamble is OK, proceeding with AOF tail...
AOF analyzed: size=132, ok_up_to=132, ok_up_to_line=1, diff=0
AOF is valid

持久化方式对比

RDB

  • 优点:RDB 文件紧凑,体积小,因此在传输速度上比较快,因此适合全量恢复。
    RDB 可以最大化 Redis 的性能:父进程在保存 RDB 文件时唯一要做的就是 fork 出一个子进程,然后这个子进程就会处理接下来的所有保存工作,父进程无须执行任何磁盘 I/O 操作。
    RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快。
  • 缺点:RDB是一个快照过程,无法完整的保存所以数据,尤其在数据量比较大时候,一旦出现故障丢失的数据将更多。
    当redis中数据集比较大时候,RDB由于RDB方式需要对数据进行完成拷贝并生成快照文件,fork的子进程会耗CPU,并且数据越大,RDB快照生成会越耗时。
    RDB文件是特定的格式,阅读性差,由于格式固定,可能存在不兼容情况。

AOF

  • 优点:数据更完整,秒级数据丢失(取决于设置fsync策略)。
    兼容性较高,由于是基于redis通讯协议而形成的命令追加方式,无论何种版本的redis都兼容,再者aof文件是明文的,可阅读性较好。
  • 缺点:数据文件体积较大,即使有重写机制,但是在相同的数据集情况下,AOF文件通常比RDB文件大。
    相对RDB方式,AOF速度慢于RDB,并且在数据量大时候,恢复速度AOF速度也是慢于RDB。
    由于频繁地将命令同步到文件中,AOF持久化对性能的影响相对RDB较大,但是对于我们来说是可以接受的。

混合持久化

  • 优点:
    混合持久化结合了RDB持久化 和 AOF 持久化的优点, 由于绝大部分都是RDB格式,加载速度快,同时结合AOF,增量的数据以AOF方式保存了,数据更少的丢失。
  • 缺点:兼容性差,一旦开启了混合持久化,在4.0之前版本都不识别该aof文件(兼容性问题),同时由于前部分是RDB格式,阅读性较差。

更多关于redis的知识分享,请前往博客主页。编写过程中,难免出现差错,敬请指出

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

margu_168

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值