|NO.Z.00022|——————————|BigDataEnd|——|Hadoop&Redis.V04|——|Redis.v04|AOF重写机制|

一、AOF重写、触发方式、混合持久化
### --- AOF记录数据的变化过程

~~~     AOF记录数据的变化过程,越来越大,需要重写“瘦身”
~~~     Redis可以在 AOF体积变得过大时,自动地在后台(Fork子进程)对 AOF进行重写。
~~~     重写后的新 AOF文件包含了恢复当前数据集所需的最小命令集合。 
~~~     所谓的“重写”其实是一个有歧义的词语, 实际上,
~~~     AOF 重写并不需要对原有的 AOF 文件进行任何写入和读取, 它针对的是数据库中键的当前值。
### --- 举例如下:

set s1 11
set s1 22 ------- > set s1 33
set s1 33
#没有优化的:
set s1 11
set s1 22
set s1 33
#优化后:
set s1 33
lpush list1 1 2 3
lpush list1 4 5 6 -------- > list1 1 2 3 4 5 6
#优化后
lpush list1 1 2 3 4 5 6
### --- Redis 不希望 AOF 重写造成服务器无法处理请求, 

~~~     # 所以 Redis 决定将 AOF 重写程序放到(后台)子进程里执行, 这样处理的最大好处是:
~~~     # 子进程进行 AOF 重写期间,
~~~     主进程可以继续处理命令请求。 2、子进程带有主进程的数据副本,
~~~     使用子进程而不是线程,可以在避免锁的情况下,保证数据的安全性。
~~~     # 不过, 使用子进程也有一个问题需要解决: 
~~~     因为子进程在进行 AOF 重写期间, 主进程还需要继续处理命令, 
~~~     而新的命令可能对现有的数据进行修改, 
~~~     这会让当前数据库的数据和重写后的 AOF 文件中的数据不一致。

~~~     # 为了解决这个问题, 
~~~     Redis 增加了一个 AOF 重写缓存, 这个缓存在 fork 出子进程之后开始启用,
~~~     Redis 主进程在接到新的写命令之后, 
~~~     除了会将这个写命令的协议内容追加到现有的 AOF 文件之外,还会追加到这个缓存中。
### --- 重写过程分析(整个重写操作是绝对安全的):

~~~     Redis 在创建新 AOF 文件的过程中,会继续将命令追加到现有的 AOF 文件里面,
~~~     即使重写过程中发生停机,现有的 AOF 文件也不会丢失。
~~~     而一旦新 AOF 文件创建完毕,Redis 就会从旧 AOF 文件切换到新 AOF 文件,
~~~     并开始对新 AOF 文件进行追加操作。
~~~     当子进程在执行 AOF 重写时, 
~~~     # 主进程需要执行以下三个工作:
~~~     # 处理命令请求。 
~~~     将写命令追加到现有的 AOF 文件中。 将写命令追加到 AOF 重写缓存中。 这样一来可以保证:
~~~     # 现有的 AOF 功能会继续执行,
~~~     即使在 AOF 重写期间发生停机,也不会有任何数据丢失。 
~~~     所有对数据库进行修改的命令都会被记录到 AOF 重写缓存中。 
~~~     当子进程完成 AOF 重写之后, 它会向父进程发送一个完成信号, 
~~~     父进程在接到完成信号之后, 会调用一个信号处理函数, 并完成以下工作:

~~~     # 将 AOF 重写缓存中的内容全部写入到新 AOF 文件中。 
~~~     对新的 AOF 文件进行改名,覆盖原有的 AOF 文件。
### --- Redis数据库里的+AOF重写过程中的命令------->新的AOF文件---->覆盖老的

~~~     当步骤 1 执行完毕之后, 现有 AOF 文件、新 AOF 文件和数据库三者的状态就完全一致了。
~~~     当步骤 2 执行完毕之后, 程序就完成了新旧两个 AOF 文件的交替。
~~~     这个信号处理函数执行完毕之后, 主进程就可以继续像往常一样接受命令请求了。 
~~~     在整个 AOF 后台重写过程中, 只有最后的写入缓存和改名操作会造成主进程阻塞, 
~~~     在其他时候, AOF 后台重写都不会对主进程造成阻塞, 这将 AOF 重写对性能造成的影响降到了最低。
二、以上就是 AOF 后台重写, 也即是 BGREWRITEAOF 命令(AOF重写)的工作原理。
三、触发方式
### --- 配置触发
~~~     在redis.conf中配置

[root@linux123 ~]# vim /opt/yanqi/servers/redis/bin/redis.conf
# 表示当前aof文件大小超过上一次aof文件大小的百分之多少的时候会进行重写。如果之前没有重写过,以启动时aof文件大小为准
auto-aof-rewrite-percentage 100
# 限制允许重写最小aof文件大小,也就是文件大小小于64mb的时候,不需要进行优化
auto-aof-rewrite-min-size 64mb
### --- 执行bgrewriteaof命令

127.0.0.1:6379> bgrewriteaof
Background append only file rewriting started
### --- 混合持久化

~~~     RDB和AOF各有优缺点,Redis 4.0 开始支持 rdb 和 aof 的混合持久化。
~~~     如果把混合持久化打开,aofrewrite 的时候就直接把 rdb 的内容写到 aof 文件开头。
~~~     RDB的头+AOF的身体---->appendonly.aof
~~~     开启混合持久化
~~~     # aof-use-rdb-preamble yes

~~~     我们可以看到该AOF文件是rdb文件的头和aof格式的内容,
~~~     在加载时,首先会识别AOF文件是否以REDIS字符串开头,
~~~     如果是就按RDB格式加载,加载完RDB后继续按AOF格式加载剩余部分。
### --- AOF文件的载入与数据还原

~~~     因为AOF文件里面包含了重建数据库状态所需的所有写命令,
~~~     所以服务器只要读入并重新执行一遍AOF文件里面保存的写命令,
~~~     就可以还原服务器关闭之前的数据库状态 Redis读取AOF文件并还原数据库状态的详细步骤如下: 
~~~     # 创建一个不带网络连接的伪客户端(fake client):
~~~     因为Redis的命令只能在客户端上下文中执行,
~~~     而载入AOF文件时所使用的命令直接来源于AOF文件而不是网络连接,
~~~     所以服 务器使用了一个没有网络连接的伪客户端来执行AOF文件保存的写命令,
~~~     伪客户端执行命令 的效果和带网络连接的客户端执行命令的效果完全一样
~~~     # 从AOF文件中分析并读取出一条写命令 
~~~     # 使用伪客户端执行被读出的写命令 
~~~     # 一直执行步骤2和步骤3,直到AOF文件中的所有写命令都被处理完毕为止 当完成
四、以上步骤之后,AOF文件所保存的数据库状态就会被完整地还原出来,整个过程如下图所示:

 
 
 
 
 
 
 
 
 

Walter Savage Landor:strove with none,for none was worth my strife.Nature I loved and, next to Nature, Art:I warm'd both hands before the fire of life.It sinks, and I am ready to depart
                                                                                                                                                   ——W.S.Landor

 

posted on   yanqi_vip  阅读(16)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

导航

统计

点击右上角即可分享
微信分享提示