240_Redis_数据持久化RDB_AOF

网友投稿 729 2022-05-28

Redis 持久化 RDB、AOF

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\r\nset\r\n\r\nnewkey3\r\n\r\nn3

*3

set

newkey3

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性能

RDB与 AOF比,恢复大数据集时, 速度更快

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 协议的格式来保存,新命令会被追加到文件的末尾

缺点:

240_Redis_数据持久化RDB_AOF

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部分头写入

Redis 任务调度

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:【JavaScript】页面捕捉和正则表示
下一篇:Redis源码剖析之RDB
相关文章