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 文件。

相关推荐
高梦轩13 分钟前
MySQL 故障排查与优化
数据库·mysql
吴声子夜歌28 分钟前
Node.js——操作MySQL数据库
数据库·mysql·node.js
爱丽_29 分钟前
MySQL 锁等待与死锁进阶:怎么看等待、怎么降冲突(工程化套路)
数据库·mysql
心有—林夕39 分钟前
MySQL 误操作恢复完全指南
android·数据库·mysql
夕除41 分钟前
Mysql--15
java·数据库·mysql
野生技术架构师1 小时前
掌握SQL窗口函数,轻松处理复杂数据分析
数据库·sql·数据分析
会飞的大可1 小时前
NoSQL:从原理到实践的全景指南
数据库·nosql
刘~浪地球2 小时前
Redis 从入门到精通(四):字符串操作详解
数据库·redis·缓存
荒川之神2 小时前
MySQL 商品拉链表 完整最终版(配备了全套存储过程)
数据库·mysql
admin and root2 小时前
从资产收集FUZZ接口到SQL注入案例
网络·数据库·sql·安全·web安全·渗透测试·log4j