当前位置: 首页 > news >正文

write-ahead-log与append-only-file的原理

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

    无论是RMSDB,还是NOSQL DB,如何最大程度上保证故障时的数据恢复,都涉及到数据持久化的技术。本位重点说明write-ahead-log与append-only-file这两种持久化机制的原理。

    write-ahead-log,WAL日志,是数据库中一种高效的日志算法。从数据库原理而言,它实现的是redo日志模式。即修改数据库时,不直接修改数据库内容,而是将修改完的数据写入日志同步到磁盘上,这样对其他读进程就没有影响。如果数据库崩溃,重启后扫描日志文件,然后更新到数据库中。为了提高效率,WAL日志模式提供checkpoint操作,来定时进行数据更新操作。

    以SQLite、MapDB为例,WAL的实现就是是按照上面原理来的。在更新数据页时,会将更新完的页先同步到磁盘上,并定时进行checkpoint操作。读数据库的时候,为了读到最新的页面,需要扫描日志文件,得到最新的数据页。为了提高日志文件扫描速度,还需要设计一些wal-index索引来加快对WAL日志的操作速度。

    append-only-file,AOF日志,以Redis为例。在Redis异常死掉时,最近的数据会丢失(丢失数据的多少视你save策略而定),当业务量很大时,可能丢失的数据会很多。Append-only方法可以做到全部数据不丢失,但Redis的性能就要差些。AOF就可以做到全程持久化,开启AOF之后,Redis每执行一个修改数据的命令,都会把它添加到aof文件中,当Redis重启时,将会读取AOF文件进行“Log-Rewriting 重放”以恢复到Redis关闭前的最后时刻。

    Log-Rewriting随着AOF文件越来越大,重放速度会越来越慢。但是AOF中如同流水账一样,会记录很多某一个key的全部变化过程。因此Redis有了一种比较有意思的特性:会在后台重建AOF文件,而不会影响client端操作。在任何时候执行BGREWRITEAOF命令,会对当前AOF中的数据进行整合,为每个key重新生成最短序列的AOF文件,这些数据完全可以用于构建当前某个Key的数据情况,而不会存在多余的变化情况(比如状态变化,计数器变化等),从而缩小了AOF文件的大小。所以当使用AOF时,redis推荐同时使用BGREWRITEAOF。

    AOF文件刷新的方式,有三种,参考配置参数appendfsync :appendfsync always每提交一个修改命令都调用fsync刷新到AOF文件,非常非常慢,但也非常安全;appendfsync everysec每秒钟都调用fsync刷新到AOF文件,很快,但可能会丢失一秒以内的数据;appendfsync no依靠OS进行刷新,redis不主动刷新AOF,这样最快,但安全性就差。默认并推荐每秒刷新,这样在速度和安全上都做到了兼顾。

    LOG Rewrite的工作原理:同样用到了copy-on-write:首先redis会fork一个子进程;子进程将最新的AOF写入一个临时文件;父进程增量的把内存中的最新执行的修改写入(这时仍写入旧的AOF,rewrite如果失败也是安全的);当子进程完成rewrite临时文件后,父进程会收到一个信号,并把之前内存中增量的修改写入临时文件末尾;这时redis将旧AOF文件重命名,临时文件重命名,开始向新的AOF中写入。

转载于:https://my.oschina.net/blacklands/blog/875179

相关文章:

  • sass中的三种循环
  • 【腾讯Bugly干货分享】经典随机Crash之一:线程安全
  • 基于Docker搭建Redis主从
  • Centos6.5安装lvs+keepalived集群
  • FTP服务系列一FTP的基础知识以及服务器端的配置
  • vsftpd.conf 详解与实例配置
  • swift中UISearchBar的使用
  • MSP项目群管理介绍
  • cmake 添加头文件目录,链接动态、静态库(转载)
  • Phantomjs v.2.1 addCookie()始终返回错误
  • 在shell中编写函数
  • Gartner:自建大数据安全分析平台恐难逃失败厄运!
  • Linux A机器免密码SSH登录B机器
  • Python安装pandas
  • Play 2D games on Pixel running Android Nougat (N7.1.2) with Daydream View VR headset
  • 【跃迁之路】【585天】程序员高效学习方法论探索系列(实验阶段342-2018.09.13)...
  • 77. Combinations
  • iOS | NSProxy
  • Leetcode 27 Remove Element
  • mysql外键的使用
  • vue--为什么data属性必须是一个函数
  • 创建一个Struts2项目maven 方式
  • 从0搭建SpringBoot的HelloWorld -- Java版本
  • 道格拉斯-普克 抽稀算法 附javascript实现
  • 强力优化Rancher k8s中国区的使用体验
  • 让你成为前端,后端或全栈开发程序员的进阶指南,一门学到老的技术
  • 如何用Ubuntu和Xen来设置Kubernetes?
  • 如何用vue打造一个移动端音乐播放器
  • 使用 Docker 部署 Spring Boot项目
  • 数据库写操作弃用“SELECT ... FOR UPDATE”解决方案
  • 数组大概知多少
  • 想晋级高级工程师只知道表面是不够的!Git内部原理介绍
  • 《天龙八部3D》Unity技术方案揭秘
  • gunicorn工作原理
  • SAP CRM里Lead通过工作流自动创建Opportunity的原理讲解 ...
  • (1)常见O(n^2)排序算法解析
  • (zt)基于Facebook和Flash平台的应用架构解析
  • (超简单)构建高可用网络应用:使用Nginx进行负载均衡与健康检查
  • (仿QQ聊天消息列表加载)wp7 listbox 列表项逐一加载的一种实现方式,以及加入渐显动画...
  • (附源码)计算机毕业设计SSM教师教学质量评价系统
  • (实战篇)如何缓存数据
  • (五)IO流之ByteArrayInput/OutputStream
  • (一)【Jmeter】JDK及Jmeter的安装部署及简单配置
  • (转)http-server应用
  • ******之网络***——物理***
  • .net图片验证码生成、点击刷新及验证输入是否正确
  • @KafkaListener注解详解(一)| 常用参数详解
  • @TableLogic注解说明,以及对增删改查的影响
  • [04] Android逐帧动画(一)
  • [CakePHP] 在Controller中使用Helper
  • [CF543A]/[CF544C]Writing Code
  • [dart学习]第四篇:函数
  • [HNOI2018]排列
  • [Linux] - 定时任务crontab
  • [MZ test.16]P1 评测