redis持久化篇AOF与RDB详解

AOF日志

定义:redis每执行一条命令,就将该命令已追加的方式写入到一个文件里,然后重启redis的时候,先去读取这个文件里的命令,并且执行它,就可以实现redis持久化。这种保存写操作命令到日志的持久化方式是redis里面的AOF持久化功能。

注意:

redis是先执行操作命令后将命令记录到AOF日志。

两个好处:

1.避免额外的开销,当该命令有错误时,进行语法检查,就不会将错误命令记录到日志。

2.不会阻塞当前写操作命令的执行,因为当写操作执行成功后才会执行记录到AOF日志。

AOF文件中 *3 代表当前命令有三个部分,每部分都是以$+数字开头,数字代表每个命令的字符串长度。

三种写回策略

redis写入AOF日志的过程:

我们来解释一下上图操作:

1.redis执行写操作命令,会将命令加入aof_buf缓冲区。

2.write系统调用后,将缓冲区的数据写入到aof文件,此时并没有写入磁盘。

3.具体什么时候i写入磁盘有内核决定。

1.每次操作都写入日志

1.Always,这个单词的意思是总是,所以他的意思是每次写操作命令执行完后,同步将AOF日志数据写会硬盘。

2.每秒写入日志

2.Everysec,每次写操作命令执行完后,先将命令写入到+AOF+文件的内核缓冲区,然后每隔一秒将缓冲区里的内容写回到硬盘。

3.操作系统控制写回机制

3.No,意味着不由+Redis+控制写回硬盘的时机,转交给操作系统控制写回的时机,也就是每次写操作命令执行完后,先将命令写入到+AOF+文件的内核缓冲区,再由操作系统决定何时将缓冲区内容写回硬盘。

AOF重写机制

AOF日志是一个文件,如果文件过大就会带来性能问题,Redis为了避免AOF文件越写越大,提供了重写机制,来压缩AOF文件。

AOF重写机制是在文件重写时,读取当前数据库中的所有键值对,然后将每一个键值对用一条·命令记录到新的AOF文件,等全部记录完成后,然后将新的AOF文件替换掉旧的AOF文件。

AOF后台重写

写入AOF日志的操作虽然是在主进程中完成的,是因为他写入的内容不多,所以一般不太影响命令的操作。但是在触发AOF重写机制时这个过程是很耗时的,所以1redis的重写机制是由后台子进程来完成的。

两个好处:

子进程进行AOF重写期间,主进程可以继续处理命令请求,从而避免阻塞主进程。

子进程带有主进程的数据副本。

为什么使用进程而不使用进程?

多线程之间会共享数据,共享内存,那么在修改共享数据的时候需要加锁保证数据安全,从而降低性能。

子进程重写期间会有两个过程导致主进程阻塞

创建子进程途中,由于要复制父进程的页表等数据结构,阻塞的时间跟页表的大小有关,页表越大,阻塞的时间越长。

创建子进程后,如果子进程或父进程修改了共享数据,就会发生写时复制,注意这里只会复制主进程修改的物理内存数据,没修改的还是与子进程共享。

子进程在重写时,主进程仍然可以正常处理命令。如果此时主进程对已经存在的key_value键值对进行修改,此时这个key_value数据在子进程的内存数据就跟主进程不一样了,为了解决这种数据不一致的问题,redis设置了一个AOF重写缓冲区。

再重写AOF文件期间,redis执行的命令都会保存在AOF缓冲区和·AOF重写缓冲区。

三个工作:

执行客户端发下来的命令·。

将执行后的写命令追加到AOF缓冲区。

将执行后的写命令追加到AOF重写缓冲区。

当子进程完成重写工作后,回向主进程发送一条信号,信号是通信间的一种方式,且是异步的。

主进程收到信号后,会调用信号处理函数,该函数主要做以下工作

将AOF重写缓冲区中的所有内容加到新的AOF文件里。

新的AOF文件覆盖掉现有的AOF文件。

AOF总结

AOF日志:当redis每执行一条命令,就将其写入到aof_buf缓冲区,通过三种写回策略将缓冲区内容写入到AOF文件,当AOF文件过大时,通过AOF后台重写机制,压缩体积。

RDB快照

定义:RDB快照就是记录某一瞬间的内存数据,记录的是实际数据即二进制数据。因此在redis恢复数据时采用RDB会比AOF高一些,因为直接将RDB文件读入内存就可以了。

快照怎么用?

redis提供了两种方式来生成RDB文件,分别是save和bgsave,他们的主要区别在于是否在主线程中执行:

执行了save命令就会在主线程中生成RDB文件,可能会阻塞主线程。

执行了bgsave命令后,会创建一个子进程来生成RDB文件,这样可以避免主线程的阻塞。

RDB文件加载是在服务器启动时自动执行。

Redis 还可以通过配置文件的选项来实现每隔一段时间自动执行一次 bgsave 命令,通常可能设置至少 5 分钟才保存一次快照,这时如果 Redis 出现宕机等情况,则意味着最多可能丢失 5 分钟数据。

执行快照时,数据能被修改吗?

执行 bgsave 过程中,Redis 依然可以继续处理操作命令的,也就是数据是能被修改的。

那具体如何做到到呢?关键的技术就在于写时复制技术。

创建子进程时:

修改共享数据后:

如果主线程(父进程)要修改共享数据里的某一块数据(比如键值对 A)时,就会发生写时复制,于是这块数据的物理内存就会被复制一份(键值对 A'),然后主线程在这个数据副本(键值对 A')进行修改操作。与此同时,bgsave 子进程可以继续把原来的数据(键值对 A)写入到 RDB 文件。

RDB与AOF合体

尽管 RDB 比 AOF 的数据恢复速度快,但是快照的频率不好把握:

  • 如果频率太低,两次快照间一旦服务器发生宕机,就可能会比较多的数据丢失;
  • 如果频率太高,频繁写入磁盘和创建子进程会带来额外的性能开销。

RDB与AOF合体混合使用 AOF 日志和内存快照,也叫混合持久化。混合持久化工作在 AOF 日志重写过程。

如果想要开启混合持久化功能,可以在 Redis 配置文件将下面这个配置项设置成 yes:

复制代码
aof-use-rdb-preamble yes

当开启了混合持久化时,在 AOF 重写日志时,fork 出来的重写子进程会先将与主线程共享的内存数据以 RDB 方式写入到 AOF 文件,然后主线程处理的操作命令会被记录在重写缓冲区里,重写缓冲区里的增量命令会以 AOF 方式写入到 AOF 文件,写入完成后通知主进程将新的含有 RDB 格式和 AOF 格式的 AOF 文件替换旧的的 AOF 文件。

相关推荐
@老蝴2 小时前
MySQL - 索引
数据库·mysql
tgethe2 小时前
MySQL 进阶攻略
数据库·mysql
亮子AI2 小时前
【node.js MySQL】node.js 如何连接 MySQL?
数据库·mysql·node.js
程序员根根2 小时前
Web 开发必学:Java 数据库操作从 JDBC 到 MyBatis 的进阶之路
数据库·后端
全栈工程师修炼指南2 小时前
Nginx | HTTPS 加密传输:Nginx 反向代理与上游服务 SSL 双向认证实践
网络·数据库·nginx·https·ssl
德迅云安全-小潘2 小时前
网络空间资产安全发展演进与实践框架
数据库·web安全
极限实验室2 小时前
APM(二):监控 Python 服务
数据库
川川菜鸟2 小时前
谷歌安全告警(Chrome 红页)完整处理指南
数据库·chrome·安全
DemonAvenger2 小时前
Redis缓存穿透、击穿与雪崩:从问题剖析到实战解决方案
数据库·redis·性能优化