Redis--基础知识点--17--rdb_aof

2023-11-11

1 持久化

1.1 什么是持久化

持久化(Persistence),即把数据(如内存中的对象)保存到可永久保存的存储设备中(如磁盘)。
持久化Redis所有数据保持在内存中,对数据的更新将异步地保存到磁盘上。
在这里插入图片描述

1.2 持久化的实现方式

快照方式持久化

快照方式持久化就是在某时刻把所有数据进行完整备份。

例:Mysql的Dump方式、Redis的RDB方式。

写日志方式持久化

写日志方式持久化就是把用户执行的所有写指令(增删改)备份到文件中,还原数据时只需要把备份的所有指令重新执行一遍即可。

例:Mysql的Binlog、Redis的AOF、Hbase的HLog。


2 RDB 详解

RDB 是 Redis 默认的持久化方案。在指定的时间间隔内,执行指定次数的写操作,则会将内存中的数据写入到磁盘中。即在指定目录下生成一个dump.rdb文件。Redis 重启会通过加载dump.rdb文件恢复数据。

2.1 从配置文件了解RDB

打开 redis.conf 文件,找到 SNAPSHOTTING 对应内容

# RDB自动持久化规则
# 当 900 秒内有至少有 1 个键被改动时,自动进行数据集保存操作
save 900 1
# 当 300 秒内有至少有 10 个键被改动时,自动进行数据集保存操作
save 300 10
# 当 60 秒内有至少有 10000 个键被改动时,自动进行数据集保存操作
save 60 10000

# RDB持久化文件名
dbfilename dump-<port>.rdb

# 数据持久化文件存储目录
dir /var/lib/redis

# bgsave发生错误时是否停止写入,通常为yes
stop-writes-on-bgsave-error yes

# rdb文件是否使用压缩格式,Redis采用LZF压缩方式,但占用了一点CPU的时间。若关闭该选项,但会导致数据库文件变的巨大。建议开启。
rdbcompression yes

# 是否对rdb文件进行校验和检验,通常为yes
rdbchecksum yes

2.2 RDB文件的创建及通过RDB文件恢复数据

在这里插入图片描述
(1) RDB持久化方式能够在指定的时间间隔能对你的数据进行快照存储。
(2) 在默认情况下, Redis 将数据库快照保存在名字为 dump.rdb的二进制文件中。文件位置可通过redis.conf中的dir设置
(3) 在 Redis 运行时, RDB 程序将当前内存中的数据库快照保存到磁盘文件中, 在 Redis 重启动时, RDB 程序可以通过载入 RDB 文件来还原数据库的状态。

2.3 触发RDB快照

1 在指定的时间间隔内,执行指定次数的写操作
2 执行save(阻塞, 只管保存快照,其他的等待) 或者是bgsave (异步)命令
3 执行flushall 命令,清空数据库所有数据,意义不大。
4 执行shutdown 命令,保证服务器正常关闭且不丢失任何数据,意义…也不大。

原理

工作方式
当 Redis 需要保存 dump.rdb 文件时, 服务器执行以下操作:

  • (1) Redis 调用forks。同时拥有父进程和子进程。
  • (2) 子进程将数据集写入到一个临时 RDB 文件中。
  • (3) 当子进程完成对新 RDB 文件的写入时,Redis 用新 RDB 文件替换原来的 RDB 文件,并 删除旧的 RDB 文件。

这种工作方式使得 Redis 可以从写时复制(copy-on-write)机制中获益。

save命令(同步数据到磁盘上)

save 命令执行一个同步操作,以RDB文件的方式保存所有数据的快照。

127.0.0.1:6379> save
OK

save命令
由于 save 命令是同步命令,会占用Redis的主进程。若Redis数据非常多时,save命令执行速度会非常慢,阻塞所有客户端的请求。
因此很少在生产环境直接使用SAVE 命令,可以使用BGSAVE 命令代替。如果在BGSAVE命令的保存数据的子进程发生错误的时,用 SAVE命令保存最新的数据是最后的手段。
在这里插入图片描述
bgsave命令(异步保存数据到磁盘上)

bgsave 命令执行一个异步操作,以RDB文件的方式保存所有数据的快照。

127.0.0.1:6379> bgsave
Background saving started

Redis使用Linux系统的fock()生成一个子进程来将DB数据保存到磁盘,主进程继续提供服务以供客户端调用。
如果操作成功,可以通过客户端命令LASTSAVE来检查操作结果。
在这里插入图片描述
savebgsave 对比

命令 save bgsave
IO类型 同步 异步
阻塞? 是(阻塞发生在fock(),通常非常快)
复杂度 O(n) O(n)
优点 不会消耗额外的内存 不阻塞客户端命令
缺点 阻塞客户端命令 需要fock子进程,消耗内存

自动生成RDB

除了手动执行 save 和 bgsave 命令实现RDB持久化以外,Redis还提供了自动自动生成RDB的方式。

你可以通过配置文件对 Redis 进行设置, 让它在“ N 秒内数据集至少有 M 个改动”这一条件被满足时, 自动进行数据集保存操作。
比如说, 以下设置会让 Redis 在满足“ 60 秒内有至少有 1000 个键被改动”这一条件时, 自动进行数据集保存操作:

save 60 1000

在这里插入图片描述

2.4 RDB 的优缺点

优点:

  • 1 适合大规模的数据恢复。
  • 2 如果业务对数据完整性和一致性要求不高,RDB是很好的选择。

缺点:

  • 1 数据的完整性和一致性不高,因为RDB可能在最后一次备份时宕机了。
  • 2 备份时占用内存,因为Redis 在备份时会独立创建一个子进程,将数据写入到一个临时文件(此时内存中的数据是原来的两倍哦),最后再将临时文件替换之前的备份文件。

所以Redis 的持久化和数据的恢复要选择在夜深人静的时候执行是比较合理的。

2.5 操作演示

[root@itdragon bin]# vim redis.conf
save 900 1
save 120 5
save 60 10000
[root@itdragon bin]# ./redis-server redis.conf
[root@itdragon bin]# ./redis-cli -h 127.0.0.1 -p 6379
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379> set key1 value1
OK
127.0.0.1:6379> set key2 value2
OK
127.0.0.1:6379> set key3 value3
OK
127.0.0.1:6379> set key4 value4
OK
127.0.0.1:6379> set key5 value5
OK
127.0.0.1:6379> set key6 value6
OK
127.0.0.1:6379> SHUTDOWN
not connected> QUIT
[root@itdragon bin]# cp dump.rdb dump_bk.rdb
[root@itdragon bin]# ./redis-server redis.conf
[root@itdragon bin]# ./redis-cli -h 127.0.0.1 -p 6379
127.0.0.1:6379> FLUSHALL 
OK
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379> SHUTDOWN
not connected> QUIT
[root@itdragon bin]# cp dump_bk.rdb  dump.rdb
cp: overwrite `dump.rdb'? y
[root@itdragon bin]# ./redis-server redis.conf
[root@itdragon bin]# ./redis-cli -h 127.0.0.1 -p 6379
127.0.0.1:6379> keys *
1) "key5"
2) "key1"
3) "key3"
4) "key4"
5) "key6"
6) "key2"

第一步:vim 修改持久化配置时间,120秒内修改5次则持久化一次。
第二步:重启服务使配置生效。
第三步:分别set 5个key,过两分钟后,在bin的当前目录下会自动生产一个dump.rdb文件。(set key6 是为了验证shutdown有触发RDB快照的作用)
第四步:将当前的dump.rdb 备份一份(模拟线上工作)。
第五步:执行FLUSHALL命令清空数据库数据(模拟数据丢失)。
第六步:重启Redis服务,恢复数据…咦????( ′◔ ‸◔`)。数据是空的????这是因为FLUSHALL也有触发RDB快照的功能。
第七步:将备份的 dump_bk.rdb 替换 dump.rdb 然后重新Redis。

注意点:SHUTDOWN 和 FLUSHALL 命令都会触发RDB快照,这是一个坑,请大家注意。

其他命令:

  • keys * 匹配数据库中所有 key
  • save 阻塞触发RDB快照,使其备份数据
  • FLUSHALL 清空整个 Redis 服务器的数据(几乎不用)
  • SHUTDOWN 关机走人(很少用)

2.6 备份类型

通过快照备份,全量备份


3 AOF 详解

快照功能(RDB)并不是非常耐久(durable): 如果 Redis 因为某些原因而造成故障停机, 那么服务器将丢失最近写入、且仍未保存到快照中的那些数据。 从 1.1 版本开始, Redis 增加了一种完全耐久的持久化方式: AOF 持久化。

你可以在配置文件中打开AOF方式:

appendonly yes

打开AOF后, 每当 Redis 执行一个改变数据集的命令时(比如 SET), 这个命令就会被追加到 AOF 文件的末尾。这样的话, 当 Redis 重新启时, 程序就可以通过重新执行 AOF 文件中的命令来达到重建数据集的目的。

3.1 从配置文件了解AOF

打开 redis.conf 文件,找到 APPEND ONLY MODE 对应内容

# 开启AOF持久化方式
appendonly yes

# AOF持久化文件名
appendfilename appendonly-<port>.aof

# 每秒把缓冲区的数据同步到磁盘
appendfsync everysec

# 数据持久化文件存储目录
dir /var/lib/redis

# 是否在执行重写时不同步数据到AOF文件
# 这里的 yes,就是执行重写时不同步数据到AOF文件
no-appendfsync-on-rewrite yes

# 触发AOF文件执行重写的最小尺寸
auto-aof-rewrite-min-size 64mb
# 触发AOF文件执行重写的增长率
auto-aof-rewrite-percentage 100
# 当AOF文件大小是上次rewrite后大小的一倍且文件大于64M时触发。一般都设置为3G,64M太小了。

3.2 AOF文件的创建及根据AOF文件恢复数据

AOF运行原理 - 创建
在这里插入图片描述
AOF运行原理 - 恢复
在这里插入图片描述
正常情况下,将appendonly.aof 文件拷贝到redis的安装目录的bin目录下,重启redis服务即可。但在实际开发中,可能因为某些原因导致appendonly.aof 文件格式异常,从而导致数据还原失败,可以通过命令redis-check-aof --fix appendonly.aof 进行修复 。从下面的操作演示中体会。

3.3 触发AOF快照

根据配置文件触发,可以是每次执行触发,可以是每秒触发,可以不同步。

always

每次有新命令追加到 AOF 文件时就执行一次 fsync :非常慢,也非常安全。

always
everysec

每秒 fsync 一次:足够快(和使用 RDB 持久化差不多),并且在故障时只会丢失 1 秒钟的数据。
推荐(并且也是默认)的措施为每秒 fsync 一次, 这种 fsync 策略可以兼顾速度和安全性。
everysec
no

从不 fsync :将数据交给操作系统来处理,由操作系统来决定什么时候同步数据。更快,也更不安全的选择。
no
alwayseverysecno对比

命令 优点 缺点
always 不丢失数据 IO开销大,一般SATA磁盘只有几百TPS
everysec 每秒进行与fsync,最多丢失1秒数据 可能丢失1秒数据
no 不用管 不可控

推荐(并且也是默认)的措施为每秒 fsync 一次, 这种 fsync 策略可以兼顾速度和安全性。

3.4 AOF的重写机制

前面也说到了,AOF的工作原理是将写操作追加到文件中,文件的冗余内容会越来越多。所以聪明的 Redis 新增了重写机制。当AOF文件的大小超过所设定的阈值时,Redis就会对AOF文件的内容压缩。

AOF重写举例

因为 AOF 的运作方式是不断地将命令追加到文件的末尾, 所以随着写入命令的不断增加, AOF 文件的体积也会变得越来越大。举个例子, 如果你对一个计数器调用了 100 次 INCR , 那么仅仅是为了保存这个计数器的当前值, AOF 文件就需要使用 100 条记录(entry)。然而在实际上, 只使用一条 SET 命令已经足以保存计数器的当前值了, 其余 99 条记录实际上都是多余的。

为了处理这种情况, Redis 支持一种有趣的特性: 可以在不打断服务客户端的情况下, 对 AOF 文件进行重建(rebuild)。执行 bgrewriteaof 命令, Redis 将生成一个新的 AOF 文件, 这个文件包含重建当前数据集所需的最少命令。

Redis 2.2 需要自己手动执行 bgrewriteaof 命令; Redis 2.4 则可以通过配置自动触发 AOF 重写。
在这里插入图片描述
AOF重写作用

  • 减少磁盘占用量
  • 加速数据恢复

AOF重写原理

bgrewriteaof 命令

  • Redis bgrewriteaof 命令用于异步执行一个 AOF(AppendOnly File)文件重写操作。重写会创建一个当前AOF文件的体积优化版本。
    即使 bgrewriteaof 执行失败,也不会有任何数据丢失,因为旧的AOF文件在 bgrewriteaof 成功之前不会被修改。
    AOF 重写由 Redis 自行触发,bgrewriteaof 仅仅用于手动触发重写操作。
    具体内容:
    • 如果一个子Redis是通过磁盘快照创建的,AOF重写将会在RDB终止后才开始保存。这种情况下BGREWRITEAOF任然会返回OK状态码。从Redis 2.6起你可以通过INFO命令查看AOF重写执行情况。
    • 如果只在执行的AOF重写返回一个错误,AOF重写将会在稍后一点的时间重新调用。
      在这里插入图片描述

AOF重写配置

配置名 含义
auto-aof-rewrite-min-size 触发AOF文件执行重写的最小尺寸
auto-aof-rewrite-percentage 触发AOF文件执行重写的增长率
统计名 含义
aof_current_size AOF文件当前尺寸(字节)
aof_base_size AOF文件上次启动和重写时的尺寸(字节)

AOF重写自动触发机制,需要同时满足下面两个条件:

  • aof_current_size > auto-aof-rewrite-min-size
  • (aof_current_size - aof_base_size) * 100 / aof_base_size > auto-aof-rewrite-percentage

假设 Redis 的配置项为:

auto-aof-rewrite-min-size 64mb
auto-aof-rewrite-percentage 100

当AOF文件的体积大于64Mb,并且AOF文件的体积比上一次重写之久的体积大了至少一倍(100%)时,Redis将执行 bgrewriteaof 命令进行重写。

AOF重写的流程

在这里插入图片描述

3.5 AOF 的优缺点

优点:数据的完整性和一致性更高
缺点:因为AOF记录的内容多,文件会越来越大,数据恢复也会越来越慢。

3.6 操作演示

[root@itdragon bin]# vim appendonly.aof
appendonly yes
[root@itdragon bin]# ./redis-server redis.conf
[root@itdragon bin]# ./redis-cli -h 127.0.0.1 -p 6379
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379> set keyAOf valueAof
OK
127.0.0.1:6379> FLUSHALL 
OK
127.0.0.1:6379> SHUTDOWN
not connected> QUIT
[root@itdragon bin]# ./redis-server redis.conf
[root@itdragon bin]# ./redis-cli -h 127.0.0.1 -p 6379
127.0.0.1:6379> keys *
1) "keyAOf"
127.0.0.1:6379> SHUTDOWN
not connected> QUIT
[root@itdragon bin]# vim appendonly.aof
fjewofjwojfoewifjowejfwf
[root@itdragon bin]# ./redis-server redis.conf
[root@itdragon bin]# ./redis-cli -h 127.0.0.1 -p 6379
Could not connect to Redis at 127.0.0.1:6379: Connection refused
not connected> QUIT
[root@itdragon bin]# redis-check-aof --fix appendonly.aof 
'x              3e: Expected prefix '*', got: '
AOF analyzed: size=92, ok_up_to=62, diff=30
This will shrink the AOF from 92 bytes, with 30 bytes, to 62 bytes
Continue? [y/N]: y
Successfully truncated AOF
[root@itdragon bin]# ./redis-server redis.conf
[root@itdragon bin]# ./redis-cli -h 127.0.0.1 -p 6379
127.0.0.1:6379> keys *
1) "keyAOf"

第一步:修改配置文件,开启AOF持久化配置。
第二步:重启Redis服务,并进入Redis 自带的客户端中。
第三步:保存值,然后模拟数据丢失,关闭Redis服务。
第四步:重启服务,发现数据恢复了。(额外提一点:有教程显示FLUSHALL 命令会被写入AOF文件中,导致数据恢复失败。我安装的是redis-4.0.2没有遇到这个问题)。
第五步:修改appendonly.aof,模拟文件异常情况。
第六步:重启 Redis 服务失败。这同时也说明了,RDB和AOF可以同时存在,且优先加载AOF文件。
第七步:校验appendonly.aof 文件。重启Redis 服务后正常。

补充点:aof 的校验是通过 redis-check-aof 文件,那么rdb 的校验是不是可以通过 redis-check-rdb 文件呢???

3.7 备份类型

通过日志备份,增量备份


4 RDB和AOF的抉择

4.1 RDB 和 AOF 对比

- RDB AOF
启动优先级
体积
恢复速度
数据安全性 丢数据 根据策略决定

4.2 如何选择使用哪种持久化方式?

一般来说, 如果想达到足以媲美 PostgreSQL 的数据安全性, 你应该同时使用两种持久化功能。

如果你非常关心你的数据, 但仍然可以承受数分钟以内的数据丢失, 那么你可以只使用 RDB 持久化。

有很多用户都只使用 AOF 持久化, 但并不推荐这种方式: 因为定时生成 RDB 快照(snapshot)非常便于进行数据库备份, 并且 RDB 恢复数据集的速度也要比 AOF 恢复的速度要快。

4.3 redis重启加载load

当Redis服务器重启时,可以加载AOF文件进行数据恢复。
在这里插入图片描述
如上图,流程说明:

  • (1) AOF持久化开启且存在AOF文件时,优先加载AOF文件。
  • (2) AOF关闭或者AOF文件不存在时,加载RDB文件。
  • (3) 加载AOF/RDB文件成功后,Redis启动成功。
  • (4) AOF/RDB文件存在错误时,Redis启动失败并打印错误信息。

[参考博客]
Redis持久化 - RDB和AOF
Redis 持久化之RDB和AOF

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Redis--基础知识点--17--rdb_aof 的相关文章

随机推荐

  • 【nvivo11plus教程】02_编码与节点

    1 对文档进行编码 1 建立节点 2 使用快速编码栏进行编码 3 将整个文件编码为一个代码 4 范围编码 5 在vivo中编码 6 使用节点昵称加快编码速度 2 取消 增加和查看编码 1 编码带 2 删除编码 3 查看编码邻近区 4 增加编
  • Pandas.read_excel详解

    文章目录 基础知识 语法 参数详解 index col 参数详解 header 参数详解 usecols 参数详解 dtype 其他参数 多表读取 顺带提一句如何用pandas写数据到excel 基础知识 pandas 可以读取多种的数据格
  • DLL load failed while importing win32gui: 找不到指定的程序

    pip install pywin32 226
  • 九、软考2014年上半年软件设计师易错题整理

    文章目录 错题1 错题2 错题3 错题4 错题5 错题6 错题7 错题8 错题9 错题10 错题11 错题12 错题13 错题14 错题15 错题16 错题17 错题18 错题19 错题20 专业英语 错题1 在CPU中 常用来为ALU执行
  • 字节跳动暑期实习生一面面经 大三

    身份 双非本科大三 大二从小程序开始学起前端 之后自学前端 自我介绍 了解box sizing吗 这里脑子没转 说了不太了解 面试官特别好 是会引导着你去回答问题的 了解盒模型吗 了解的 盒模型分为标准盒模型和IE盒模型 标准盒模型是包括m
  • reg型变量怎么赋值_FPGA的wire和reg类型变量

    1 wire型 网络类型变量表示结构实体 如门 之间的物理连接 网络类型变量不能存储值 而且它必须要受到驱动器 如门或连续赋值语句 如assign 的驱动 如果没有驱动器连接到网络类型变量上 则该变量就是高阻的 即值为Z 常用的网络类型变量
  • 完美国际服务器管理修改经验倍数,魔兽地图编辑问题--修改经验倍数

    呵呵 我来说说吧 1 选择英雄 提供了多种英雄选择方式包括技能 能量圈 双击选择英雄的方式 2 点击单位 出现文本提示 可以用在选择英雄的时候 单击想要选择的英雄 出现该英雄拥有技能的文本提示 3 同类物品不能同时携带 当单位身上已经携带该
  • git错误The TLS connection was non-properly terminated解决

    问题描述 在执行hexo d发布文章时候 出现错误 error fatal unable to access https github com huanyouchen huanyouchen github io git gnutls han
  • java OA 系统开发二:数据库设计之oa数据库设计

    一 概述 oa数据库表设计 用户信息表 机构信息表 部门信息表 员工考勤 我的便签 消息管理 邮件管理 登入日志 操作日志 考勤标准 文档类型 考勤统计 我的日程 部门日程表 用户角色中间表 角色管理 角色菜单中间表 菜单父节点 菜单子节点
  • 这篇文章完美的解释了为什么有人不喜欢Spinner,当它在某些主题下出来的非常丑

    这篇文章完美的解释了为什么有人不喜欢Spinner 当它在某些主题下出来的非常丑 http www jcodecraeer com a anzhuokaifa androidkaifa 2015 0105 2264 html
  • 华为OD机试真题 Java 实现【最远足迹】【2022Q4 100分】,附详细解题思路

    目录 一 题目描述 二 输入描述 三 输出描述 四 解题思路 五 Java算法源码 六 效果展示 华为OD机试 2023B卷题库疯狂收录中 刷题点这里 一 题目描述 某探险队负责对地下洞穴进行探险 探险队成员在进行探险任务时 随身携带的记录
  • Java基础小测总结

    1 非抽象实现接口后 实现接口中方法的原则 两同两小一大原则 方法名相同 参数类型相同 子类返回类型小于等于父类方法返回类型 子类抛出异常小于父类方法抛出异常 子类访问权限大于等于父类方法访问权限 2 volatile关键字 被volati
  • 踩坑 calendar.getActualMaximum(calendar.DAY_OF_MONTH)函数

    当使用calendar getActualMaximum calendar DAY OF MONTH 获取每月最后一天时或者获取当季的最后一天时 会出现在二月的时候获取的不准确的情况 问题出现原因 代码没有动过 之前一直是使用这个时间函数来
  • 如何使用数字孪生和人工智能优化制造

    将数字孪生 digital twin 与人工智能 AI 相结合 可以减少甚至消除产品制造过程中的 臆测 几率 降低因不合理的想法实施带来的损失 那么 到底什么是数字孪生 它又是如何使现实中的生产过程变得更加高效的 CXO TALK采访了西门
  • 白嫖 IBM LinuxOne 服务器教程

    白嫖 IBM LinuxOne 教程 1 介绍 1 1前言 LinuxONE Community Cloud是IBM联合Marist大学为学生提供的用于测试应用程序和网站的平台 提供长达120天的免费VPS 温馨提醒 这个 VPS 是 S3
  • 游戏中关于跳跃的函数图像的推导以及应用

    跳跃应该是游戏开发中一个最常见的功能之一 实现的方法也有很多 这里我来讲一个我以前用的一个方法 正常的跳跃 如果使用物理引擎的话 就直接给一个向上的力就可以了 但是有一些游戏 例如跑酷 角色的移动速度都是越来越快的 而如果还是只给一个向上的
  • 【第2篇】VGG——引用最多的论文

    文章目录 摘要 1 引言 2 ConvNet配置 2 1 架构 2 2 配置 2 3 讨论 3 分类框架 3 1 训练 3 2 测试 3 3 实现细节
  • 什么是TPS,什么是QPS,区别是什么?

    一 TPS Transactions Per Second 每秒传输的事物处理个数 即服务器每秒处理的事务数 TPS包括一条消息入和一条消息出 加上一次用户数据库访问 业务TPS CAPS 每个呼叫平均TPS TPS是软件测试结果的测量单位
  • SpringBoot项目jwt生成token集成redis

    业务逻辑 1 用户登录 使用jwt生成token 2 后端把这个token返回给前端 同时把这个token作为key存储在redis中 用户对象作为value 并设置一个过期时间 3 用户以后每次访问都携带这个token 如果这个token
  • Redis--基础知识点--17--rdb_aof

    1 持久化 1 1 什么是持久化 持久化 Persistence 即把数据 如内存中的对象 保存到可永久保存的存储设备中 如磁盘 持久化Redis所有数据保持在内存中 对数据的更新将异步地保存到磁盘上 1 2 持久化的实现方式 快照方式持久