首页 > 数据库 >04 AOF日志:宕机,Redis如何避免数据丢失

04 AOF日志:宕机,Redis如何避免数据丢失

时间:2024-02-20 18:55:57浏览次数:32  
标签:AOF 04 宕机 Redis 阻塞 命令 日志 重写

Redis 的持久化主要有两大机制,即 AOF(Append Only File)日志和 RDB 快照

Redis 用于避免数据丢失的 AOF 方法


数据库的写前日志(Write Ahead Log, WAL),在实际写数据前,先把修改的数据记到日志文件中,以便故障时进行恢复。

AOF 日志正好相反,是写后日志, Redis 是先执行命令,把数据写入内存,然后才记录日志

AOF 为什么要先执行命令再记日志:

AOF 里记录的是 Redis 收到的每一条命令,这些命令是以文本形式保存的。

  1. 写后日志先让系统执行命令,只有命令能执行成功,才会被记录到日志中,否则,系统就会直接向客户端报错,避免出现记录错误命令的情况
  2. 在命令执行后才记录日志,所以不会阻塞当前的写操作。

AOF 两个潜在的风险:

  1. 如果刚执行完一个命令,还没有来得及记日志就宕机,那么这个命令和相应的数据就有丢失的风险。
  2. AOF 避免对当前命令的阻塞,但可能会给下一个操作带来阻塞风险。因为,AOF 日志也是在主线程中执行的,如果在把日志文件写入磁盘时,磁盘写压力大,导致写盘很慢,后续的操作也无法执行。

两个风险都是和 AOF 写回磁盘的时机相关的。如果能够控制一个写命令执行完后 AOF 日志写回磁盘的时机,风险即被解决。


三种写回策略:

AOF 配置项 appendfsync 的三个可选值

  • Always,同步写回:每个写命令执行完,立马同步地将日志写回磁盘;
  • Everysec,每秒写回:每个写命令执行完,只是先把日志写到 AOF 文件的内存缓冲区,每隔一秒把缓冲区中的内容写入磁盘
  • No,操作系统控制的写回:每个写命令执行完,只是先把日志写到 AOF 文件的内存缓冲区,由操作系统决定何时将缓冲区内容写回磁盘。

性能可靠性之间进行取舍


AOF重写机制

AOF 文件过大会带来的性能问题,通过AOF 重写机制把日志文件变小,因为重写机制具有“多变一”功能,即旧日志文件中的多条命令,在重写后的新日志中变成了一条命令。

虽然 AOF 重写后,日志文件会缩小,但要把整个数据库的最新数据的操作日志都写回磁盘,仍然耗时。这时需要考虑重写会不会阻塞主线程


AOF 重写会阻塞吗?

AOF 日志由主线程写回,而重写过程是由后台子进程 bgrewriteaof 来完成。

重写的过程总结为“一个拷贝,两处日志

一个拷贝:每次执行重写时,主线程 fork 出后台的 bgrewriteaof 子进程,把主线程的内存拷贝一份给 bgrewriteaof 子进程,子进程可在不影响主线程的情况下,逐一把拷贝的数据写成操作记入重写日志

因为主线程未阻塞,仍然可以处理新来的操作。此时,如果有写操作,

第一处日志:正在使用的 AOF 日志,Redis 会把这个写操作写到它的缓冲区。即使宕机,这个 AOF 日志的操作仍然是齐全的,可以用于恢复。

第二处日志:新的 AOF 重写日志,这个操作也会被写到重写日志的缓冲区。重写日志也不会丢失最新的操作。等到拷贝数据的所有操作记录重写完成后,重写日志记录的这些最新操作也会写入新的 AOF 文件,以保证数据库最新状态的记录。

AOF非阻塞的重写过程

非阻塞:是指AOF 重写子进程的执行不阻塞主线程


使用 AOF 进行故障恢复时,仍然需要把所有的操作记录都运行一遍,再加上 Redis 的单线程设计,命令操作只能一条一条按顺序执行,“重放”的过程就会很慢。


  1. AOF 日志重写过程有没有其他潜在的阻塞风险呢?如果有的话,会在哪里阻塞?
  2. AOF 重写也有一个重写日志,为什么它不共享使用 AOF 本身的日志呢?

:略

标签:AOF,04,宕机,Redis,阻塞,命令,日志,重写
From: https://www.cnblogs.com/itiancong/p/18023824

相关文章

  • 互联网信息服务算法推荐管理规定 (全文学习)2022年01月04日 本规定自2022年3月1日起施
    互联网信息服务算法推荐管理规定第一章总则第一条 为了规范互联网信息服务算法推荐活动,弘扬社会主义核心价值观,维护国家安全和社会公共利益,保护公民、法人和其他组织的合法权益,促进互联网信息服务健康有序发展,根据《中华人民共和国网络安全法》、《中华人民共和国数据安全法......
  • day04
    day04目录day04scoped解决样式冲突默认情况scoped原理data必须是一个函数组件通信通信解决方案父子通信流程props特点props校验作用语法props校验完整写法注意props&data、单向数据流共同点区别单向数据流:非父子通信—eventbus事件总线作用步骤非父子通信—provide......
  • 程序设计天梯赛个人题解 L2-047-2 锦标赛
    题目分析综合题意,将最后一场比赛视为顶层,第一轮比赛视为第一层,则有:下层每场比赛选出一个胜者,每两个下层的胜者间举行本层的一次比赛,显然这是一个二叉树。考虑还原建立每场比赛的树。由于最后一层的比赛是$2^k$个选手参加,故这是个完美二叉树,使用完全二叉树的数组储存方式,则标号......
  • Oracle 低版本客户端连接19C报错ORA-28040
    适用范围12.2+问题概述客户使用Oracle11.2客户端连接Oracle19c的时候,报错:ORA-28040:NomatchingauthenticationprotocolORA-28040:没有匹配的验证协议问题原因原因客户端与服务器的没有匹配的认证协议解决方案1、在数据库服务器上的$ORACLE_HOME/network/admin/sql......
  • ts函数04
    正常的函数//函数声明functionadd(a,b){returna+b}//函数表达式,匿名函数letadd2=function(a,b){returna+b}在ts中//TSfunctionadd3(a:number,b:number):number{//a,b都是number的类型,:number表示返回值为number  returna+b}......
  • 2045:【例5.13】蛇形填数
    #include<iostream>usingnamespacestd;intmain(){ intn; cin>>n; intb=1,i=0,j=n-1,a[n][n]; for(inti=0;i<n;i++){ for(intj=0;j<n;j++){ a[i][j]=0; } } a[i][j]=1; while(b<n*n){ while(a[i+1][j]==0&&i+1<n){......
  • ubuntu22.04安装conda
    1、获取脚本并执行wget-chttps://repo.anaconda.com/archive/Anaconda3-2020.11-Linux-x86_64.shbashAnaconda3-2020.11-Linux-x86_64.sh2、一直回车往下翻直到让输入yes如图: 3、输入完yes后,选择conda安装的路径回车的话是默认路径4、自己会安装所需的插件最后conda......
  • .NET周刊【2月第1期 2024-02-04】
    祝大家新年快乐,龙年大吉~国内文章C#/.NET/.NETCore优秀项目和框架2024年1月简报https://www.cnblogs.com/Can-daydayup/p/18000401本文介绍了公众号“追逐时光者”定期分享的C#/.NET/.NETCore优秀项目和框架,包括项目介绍、功能特点、使用方式和功能截图,并提供了源码地址。文......
  • Ubuntu20.04 问题+解决方案(不定期更新)
    问题1:Ubuntu20.04错误提醒:无法修正错误E:Unabletocorrectproblems,youhaveheldbrokenpackages.例如:解决方案:https://blog.csdn.net/weixin_44284939/article/details/122647791问题2:dpkg:errorprocessingpackage***(--configure)错误解决办法E:Sub-proce......
  • 「力扣」104. 二叉树的最大深度
    「力扣」104.二叉树的最大深度题目描述给定一个二叉树root,返回其最大深度。二叉树的最大深度是指从根节点到最远叶子节点的最长路径上的节点数。示例1:输入:root=[3,9,20,null,null,15,7]输出:3示例2:输入:root=[1,null,2]输出:2提示:树中节点的数量在[0,10......