240_Redis_数据持久化RDB_AOF

举报
alexsully 发表于 2021/11/29 15:06:17 2021/11/29
【摘要】 RDB AOF持久化

Redis 持久化 RDBAOF

  • RDB持久化方式: 指定的时间间隔对数据进行快照存储
  • AOF 持久化方式:记录每次对服务器的写操作,服务宕机时会rewrite这些操作恢复数据,AOF命令以Redis协议追加保存每次写的操作添加到文件末尾,
  • Redis还支持AOF后台重写, AOF体积不易过大

如果同时开启, AOF 优先级更高, 优先使用AOF来进行恢复, AOF完整性更高


Redis序列化协议(RESP Redis Serialization Protocol)

一种文本协议 将结构数据分为5中最小单元类型,单元结束时统一加回车换行符 \r\n


1 单行字符串以”+” 字符开头

2 多行字符串以”$” 符号开头, 后跟字符串长度

3 整数值以”;” 符号开头,后跟证书的字符串形式

4 错误消息以”-” 符号开头

5 数组以”*” 号开头, 后跟数组的长度

例 客户端- 服务端

127.0.0.1:6379> set newkey3 n3

OK

*3\r\n$3\r\nset\r\n$7\r\nnewkey3\r\n$2\r\nn3

*3

$3

set

$7

newkey3

$2

n3 


1  RDB

指定的时间间隔内内存中的数据集快照写入磁盘,恢复时是将快照文件直接读到内存里。

  • Redis会单独创建(fork)一个子进程来进行持久化
  • 会先将数据写入到一个临时文件中,待持久化过程 都结束了,再用这个临时文件替换上次持久化好的文件。
  • 整个过程中,主进程是不进行任何IO操作的。 这就确保了极高的性能。
  • 如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那 RDB方式要比AOF方式更加的高效。
  • RDB的缺点是最后一次持久化后的数据可能丢失。

 2 RDB 持久化核心思想COW

RDB 持久化会调用glibc函数fork出一个子进程,子进程完成持久化工作, 子进程做持久化不会修改内存的数据结构,仅会遍历, 父进程会继续相应客户端请求

然后子进程利用操作系统的 COW (copy-on-write) 来持久化数据

3 COW 概述:

  •  父进程 子进程都指向相同的数据页(共享内存)
  • 数据段有很多系统数据页组成
  • 父进程对某个数据页进行修改, 会将共享的数据页复制一份,在复制页上进行修改
  • 子进程仍指向旧数据页(备份时刻的数据页), 由于数据没有变化, Redis持久化也被称为快照子进程继续遍历,序列化到磁盘
  • 即使内存里数据页全部被修改,内存大小也不会超过原数据内存的2倍 (Redis里大部分数据都是冷数据)

4 优点

  •  RDB是紧凑文件, 保存了某个时间点数据集
  •  RDB 是紧凑单一文件, 方便传递, : 传给备机或者云上Redis
  •  RDB 保存文件时, 父进程会fork/clone出一个子进程, 子进程完成备份工作,父进程继续其它I/0操作 保证Redis性能
  •  RDBAOF比,恢复大数据集时, 速度更快

5 缺点

  •  RDB 无法100%保证数据不丢, 会丢失一段区间内的数据(save 900 1) 可能会丢900/15分钟内数据
  •  RDB 经常fork子进程来保存数据集到磁盘, 数据集较大时, 父进程创建fork子进程也需要时间, 肯能会有毫秒级的阻塞(无法响应客户端请求)
  •  RDB持久化 涉及到临时文件, 磁盘空间应该2倍于 数据空间

RDB持久化配置

rdb持久化核心配置参数:
vim /data/6379/redis.conf
dir /data/6379    #路径
dbfilename dump.rdb   #文件名   #save 其实触发的是bgsave
save 900 1         # 900秒(15分钟)内有1个更改
save 300 10        #300秒(5分钟)内有10个更改
save 60 10000      #60秒内有10000个更改
stop-writes-on-bgsave-error yes  # bgsave 失败之后,是否停止持久化数据到磁盘,yes 表示停止持久化,no 表示忽略错误继续写文件。
rdbchecksum yes  # 写入文件和读取文件时是否开启 RDB 文件检查,检查是否有无损坏,如果在启动是检查发现损坏,则停止启动。
rdbcompression yes  # 是否压缩 redis会采用LZF算法进行压缩, 会有cpu消耗


补充

  • Save 会阻塞正常操作
  • bgsave 异步方式 提示Background saving started  # 提示开始后台保存
  • flushall 命令用于清空 Redis 数据库,生产环境慎用,当执行flushall,则会触发自动持久化,把 RDB清空

流程


2 AOF 持久化(append-only log file)   优先级较高

记录服务器执行的所有写操作命令(增量保存),只许追加文件但不可以改写文件并在服务器启动时,通过重新执行这些命令来还原数据集。

AOF是先执行指令后写入日志(不同于mysql Hbase等WAL)

优点:

  • AOF可以使用不同的fsync策略, fsync(操作系统决定), 每秒fsync,每次写的时候fsync;依旧是后台线程进行处理,主线程处理客户端请求
  • AOF文件是日志追加,如果写过程中出现宕机未完整写入日志, 可以使用redis-check-aof工具修复
  • AOF 文件体积过大,自动在后台进行重写(bgrewriteaof)进而缩小体积(过程是安全的,重写一个新AOF文件,就AOP依旧写入,重新完进行切换)
  • AOF 文件保存了所有写操作, 更加易读,分析parse更加容易。例 手动FLUSHALL,把aof文件尾flushall去掉,重启Redis可以恢复
  • AOF 文件中的命令全部以 Redis 协议的格式来保存,新命令会被追加到文件的末尾

 

缺点:

  • AOF体积大于 RDB 导致日志记录量级比较大
  • AOF 根据不同appendfsync 策略,速度慢于RDB


AOF持久化配置

AOF持久化配置
vim /data/6379/redis.conf

appendonly yes    #是否打开aof日志功能
appendfsync always    #每1个命令,都立即同步到
aofappendfsync everysec  # 每秒每秒写1次
appendfsync no        # 取决于操作系统 写入工作交给操作系统,由操作系统判断缓冲区大小,统一写入到aof.
appendfilename "appendonly.aof"
auto-aof-rewrite-percentage 100  # 指当前aof文件比上次重写的增长比例大小 原来64M 达到128M,达到这个大小就进行 aof 重写
auto-aof-rewrite-min-size 64mb  # 最开始aof文件必须要达到这个文件时才触发,后面的每次重写就不会根据这个变量

例
127.0.0.1:6379> set newkey3 n3
OK

*3
$3
set
$7
newkey3
$2
n3

如遇到AOF文件损坏,通过/usr/local/bin/redis-check-aof --fix appendonly.aof进行恢复

AOF 持久化流程-AOF重写

子进程在进行AOF重写期间,服务器进程还要继续处理命令请求,而新的命令可能对现有的数据进行修改,这会让当前数据库的数据和重写后的AOF文件中的数据不一致

AOF文件重写过程与RDB快照bgsave工作过程相似,都是通过fork子进程,由子进程完成相应的操作
同样的在fork子进程简短的时间内,redis是阻塞的

(1)开始bgrewriteaof,判断当前有没有bgsave命令(RDB持久化)/bgrewriteaof在执行,倘若有,则这些命令执行完成以后在执行。
(2)主进程fork出子进程,在这一个短暂的时间内,redis是阻塞的。
(3)主进程fork完子进程继续接受客户端请求。此时,客户端的写请求不仅仅写入aof_buf缓冲区,还写入aof_rewrite_buf重写缓冲区。COW原理
一方面是写入aof_buf缓冲区并根据appendfsync策略同步到磁盘,保证原有AOF文件完整和正确。
另一方面写入aof_rewrite_buf重写缓冲区,保存fork之后的客户端的写请求,防止新AOF文件生成期间丢失这部分数据。

(4.1)子进程写完新的AOF文件后,向主进程发信号,父进程更新统计信息。
(4.2)主进程把aof_rewrite_buf中的数据写入到新的AOF文件。

(5)使用新的AOF文件覆盖旧的AOF文件,标志AOF重写完成。



AOF-混合持久化

4.X 版本整合策略-混合持久化 AOF重写策略

AOF 重写策略做了优化, 旧版本吧内存数据集的操作指令落地, 新版本是把内存的数据集以rdb追加到aof头部,所以新版本重写后的AOF依旧是追加日志,但恢复时先rdb恢复 在做增量的日志恢复,类似混合持久化

 

混合持久化同样也是通过bgrewriteaof完成的,不同的是当开启混合持久化时,fork出的子进程先将共享的内存副本全量的以RDB方式写入aof文件

然后在将aof_rewrite_buf重写缓冲区的增量命令以AOF方式写入到文件

写入完成后通知主进程更新统计信息,并将新的含有RDB格式和AOF格式的AOF文件替换旧的的AOF文件

混合持久化配置:

aof-use-rdb-preamble yes  # yes:开启,no:关闭

简单的说:新的AOF文件前半段是RDB格式的全量数据后半段是AOF格式的增量数据,如下图:

 

AOF日志中 关于 RDB部分头写入

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。