专栏
天翼云开发者社区

redis持久化aof重写方法

2023-12-06 11:27:34 11阅读

aof相关配置


aof-rewrite-incremental-fsync yes
# aof 开关,默认是关闭的,改为yes表示开启
appendonly no
# aof的文件名,默认
appendfilename "appendonly.aof"
# aof刷数据的策略,有no/everysec/aways
appendfsync everysec
no-appendfsync-on-rewrite no
# aof超出配置大小的比例,模式是100%,可以理解为阈值 
auto-aof-rewrite-percentage 100
# aof 配置的文件的大小,默认64mb
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
# rewrite 进行时候,rewrite 文件分两种格式,1. 先 用 rdb 序列化,序列化结果写入aof文件,然后期间积累的差异用追加aof命令格式 ,2 整个文件都是aof的命令追加格式
aof-use-rdb-preamble yes 

appendfsync 一共有3种策略

  • alays 主要有数据改动就把数据刷入磁盘,性能相对最差,但最安全
  • everysec 每隔1秒刷一次数据,redis默认的,也是redis推荐的
  • no 不主动刷,什么时候刷数据,取决于操作系统,大多数linux 30秒提交一次

aof写入:

 

 

在processCommand 函数里,解析出来执行命令,放入了client中

在eedAppendOnlyFile方法里主要是aof内容生成,方法就不具体列了,主要做了三件事
  • 组装刚执行命令的aof内容buf,将过期时间由相对转成绝对(重点)
  • 如果AOF开启的情况,将刚组装的buf放入到server.aof_buf 后
  • 如果正在重写aof,将buf写到 server.aof_rewrite_buf_blocks中(在aofRewriteBufferAppend里)

这里有几个变量

  • server.aof_buf aof缓冲区,用于存放每次执行命令后的aof信息
  • server.aof_rewrite_buf_blocks 只要是有aof的子进程,就把新产生的命令添加上去
  • server.aof_pipe_write_data_to_child aof 子进程的管道,用于将server.aof_rewrite_buf_blocks信息给子进程

在主进程执行命令后,并没有写aof文件,只是将命令拼装成了字符串,放入到了aof缓冲区server.aof_buf 中,如果有aof的子进程,将aof信息放入到server.aof_rewrite_buf_blocks 然后通过管道将该信息给到子进程。

那aof是什么时候写入到文件里呢?,别急,看下图

aof有几个场景的写入:

  • 在主流程的循环体里
    • 在循环执行前的beforesleep里
    • 在serverCron里
  • 准备停止之前调用一次
  • 通过configSetCommand设置
  • 主从复制

最终都是调用的flushAppendOnlyFile


  • aof的写入是在beforeSleep 里,在serverCron 主要是处理延期写入或者处理写入异常
  • aof通过server.aof_flush_postponed_start来延期写入,第一次将此值赋值为当前时间,写完以后置为0
  • aof通过write写入文件(获取的是文件fd对应的偏移指针,顺序写)

aof重写

 

serverCron在执行的时候,有一个backgroundRewriteDoneHandler方法,当时就有疑问,这个重写是干啥的?

然后搜索了下,发现了这个函数rewriteAppendOnlyFileBackground

我们看下这个函数的触发的时机

先说下触发时机:

  • 在周期性循环里进行
  • 通过命令调用执行aof重写
    • 一个是bgrewriteaofCommand
    • 一个是configSetCommand
  • 主从复制时触发

在serverCron里有两次调用


  • ① 位置标注的调用是为了延迟补偿
  • ②位置标注的每次在没有rdb和aof子进程的情况下都会进来
  • redis通过server.aof_rewrite_scheduled来控制aof的延迟执行

rof重写


通过以上的代码我们可以看到:

  • aof的重写过程和bgsave方式的rdb差不多的过程差不多
  • aof 重写有两种模式,一种是先写rdb,再追加aof(混合模式),一种是一路aof格式
  • aof在将虚拟内存空间里的数据写完以后,会通过wait轮训从管道server.aof_pipe_read_data_from_parent里获取增量更新的数据,增量更新在第一小节的时候,有个aofChildWriteDiffData处理器(通过FileEvent机制写入)
  • 然后aof 子父进程发送ack确认消息
  • 最后再次通过rioWrite 将ack期间追加的数据补救回来
  • 最后将rof的临时文件重命名为temp-rewriteaof-bg-进程id.aof

aof后续处理


其实到这里,aof是写到文件里了,但是并没有再改到配置的文件上?

别急,我们上一篇,或者本篇aof小结那张图。

在serverCron有一个分支处理backgroundSaveDoneHandler 和backgroundRewriteDoneHandler。上一篇,我们讲过了backgroundSaveDoneHandler,另一个方法backgroundRewriteDoneHandler没有讲,翻看代码看下


在最后

  • 将临时文件改成了真正配置的的aof文件
  • 然后又将缓冲区aof_rewrite_buf_blocks里的数据写入到了aof文件里。

redis为什么要进行aof重写呢?

  • aof记录的是所有的修改操作,随着运行越来越大;
  • redis作为一个缓存数据库,很多的数据是有有效期的,可能30秒后之前的键值就无效;
  • 这些失效的数据,对于aof后续的恢复来说是大部分都是执行无效的数据,会导致效能过低;
  • 磁盘的的占用也是一个问题,其实rdb也是这个理;
  • 0
  • 0
  • 0
0 评论
0/1000
评论(0) 发表评论
l****n

l****n

11 篇文章 0 粉丝
关注

redis持久化aof重写方法

2023-12-06 11:27:34 11阅读

aof相关配置


aof-rewrite-incremental-fsync yes
# aof 开关,默认是关闭的,改为yes表示开启
appendonly no
# aof的文件名,默认
appendfilename "appendonly.aof"
# aof刷数据的策略,有no/everysec/aways
appendfsync everysec
no-appendfsync-on-rewrite no
# aof超出配置大小的比例,模式是100%,可以理解为阈值 
auto-aof-rewrite-percentage 100
# aof 配置的文件的大小,默认64mb
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
# rewrite 进行时候,rewrite 文件分两种格式,1. 先 用 rdb 序列化,序列化结果写入aof文件,然后期间积累的差异用追加aof命令格式 ,2 整个文件都是aof的命令追加格式
aof-use-rdb-preamble yes 

appendfsync 一共有3种策略

  • alays 主要有数据改动就把数据刷入磁盘,性能相对最差,但最安全
  • everysec 每隔1秒刷一次数据,redis默认的,也是redis推荐的
  • no 不主动刷,什么时候刷数据,取决于操作系统,大多数linux 30秒提交一次

aof写入:

 

 

在processCommand 函数里,解析出来执行命令,放入了client中

在eedAppendOnlyFile方法里主要是aof内容生成,方法就不具体列了,主要做了三件事
  • 组装刚执行命令的aof内容buf,将过期时间由相对转成绝对(重点)
  • 如果AOF开启的情况,将刚组装的buf放入到server.aof_buf 后
  • 如果正在重写aof,将buf写到 server.aof_rewrite_buf_blocks中(在aofRewriteBufferAppend里)

这里有几个变量

  • server.aof_buf aof缓冲区,用于存放每次执行命令后的aof信息
  • server.aof_rewrite_buf_blocks 只要是有aof的子进程,就把新产生的命令添加上去
  • server.aof_pipe_write_data_to_child aof 子进程的管道,用于将server.aof_rewrite_buf_blocks信息给子进程

在主进程执行命令后,并没有写aof文件,只是将命令拼装成了字符串,放入到了aof缓冲区server.aof_buf 中,如果有aof的子进程,将aof信息放入到server.aof_rewrite_buf_blocks 然后通过管道将该信息给到子进程。

那aof是什么时候写入到文件里呢?,别急,看下图

aof有几个场景的写入:

  • 在主流程的循环体里
    • 在循环执行前的beforesleep里
    • 在serverCron里
  • 准备停止之前调用一次
  • 通过configSetCommand设置
  • 主从复制

最终都是调用的flushAppendOnlyFile


  • aof的写入是在beforeSleep 里,在serverCron 主要是处理延期写入或者处理写入异常
  • aof通过server.aof_flush_postponed_start来延期写入,第一次将此值赋值为当前时间,写完以后置为0
  • aof通过write写入文件(获取的是文件fd对应的偏移指针,顺序写)

aof重写

 

serverCron在执行的时候,有一个backgroundRewriteDoneHandler方法,当时就有疑问,这个重写是干啥的?

然后搜索了下,发现了这个函数rewriteAppendOnlyFileBackground

我们看下这个函数的触发的时机

先说下触发时机:

  • 在周期性循环里进行
  • 通过命令调用执行aof重写
    • 一个是bgrewriteaofCommand
    • 一个是configSetCommand
  • 主从复制时触发

在serverCron里有两次调用


  • ① 位置标注的调用是为了延迟补偿
  • ②位置标注的每次在没有rdb和aof子进程的情况下都会进来
  • redis通过server.aof_rewrite_scheduled来控制aof的延迟执行

rof重写


通过以上的代码我们可以看到:

  • aof的重写过程和bgsave方式的rdb差不多的过程差不多
  • aof 重写有两种模式,一种是先写rdb,再追加aof(混合模式),一种是一路aof格式
  • aof在将虚拟内存空间里的数据写完以后,会通过wait轮训从管道server.aof_pipe_read_data_from_parent里获取增量更新的数据,增量更新在第一小节的时候,有个aofChildWriteDiffData处理器(通过FileEvent机制写入)
  • 然后aof 子父进程发送ack确认消息
  • 最后再次通过rioWrite 将ack期间追加的数据补救回来
  • 最后将rof的临时文件重命名为temp-rewriteaof-bg-进程id.aof

aof后续处理


其实到这里,aof是写到文件里了,但是并没有再改到配置的文件上?

别急,我们上一篇,或者本篇aof小结那张图。

在serverCron有一个分支处理backgroundSaveDoneHandler 和backgroundRewriteDoneHandler。上一篇,我们讲过了backgroundSaveDoneHandler,另一个方法backgroundRewriteDoneHandler没有讲,翻看代码看下


在最后

  • 将临时文件改成了真正配置的的aof文件
  • 然后又将缓冲区aof_rewrite_buf_blocks里的数据写入到了aof文件里。

redis为什么要进行aof重写呢?

  • aof记录的是所有的修改操作,随着运行越来越大;
  • redis作为一个缓存数据库,很多的数据是有有效期的,可能30秒后之前的键值就无效;
  • 这些失效的数据,对于aof后续的恢复来说是大部分都是执行无效的数据,会导致效能过低;
  • 磁盘的的占用也是一个问题,其实rdb也是这个理;
文章来自专栏

MGR高可用

9 篇文章 1 订阅
0 评论
0/1000
评论(0) 发表评论
  • 0
    点赞
  • 0
    收藏
  • 0
    评论