文档章节

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

东皇巴顿
 东皇巴顿
发布于 2017/04/08 09:34
字数 928
阅读 264
收藏 0

    无论是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中写入。

© 著作权归作者所有

共有 人打赏支持
东皇巴顿
粉丝 3
博文 62
码字总数 73311
作品 0
海淀
技术主管
私信 提问
编写GO的WEB开发框架 (十): Log和Access_Log

日常开发中,Log是必不可少的一部份,一个易用的框架,应该提供一套易用的日志处理方法,本篇来讲一下我是怎么实现日志相关处理的,内容包括日志的开关、日志记录和方法调用以及access_log。...

TimWong
2016/03/12
66
0
Keepalived 2.0.10 发布,C 语言编写的路由软件

Keepalived 2.0.10 已发布,Keepalived 是一款用 C 编写的路由软件。该项目的主要目标是为 Linux 系统和基于 Linux 的基础设备提供简单而强大的负载均衡和高可用性。 更新内容: Fix compil...

淡漠悠然
11/15
1K
1
重归混沌/silly

silly Depend sudo apt-get install libreadline-dev(debain) yum install readline-devel(centos) Build make linux make macosx Run ./silly Config daemon, 1 --> run as daemon, 0 --> n......

重归混沌
2017/07/18
0
0
Log4j日志输出详解

log4j的初始化,Logger的实例为NOPLogger,所有Appender,委托给 rootLogger管理,今天我们来看一下,日志的打印输出。 日志输出源头为下一句 Java代码 log.info("========test daily level...

sdrkmb
2016/10/23
13
0
redis 源代码分析 – persistence

redis有全量(save/bgsave)和增量(aof)的持久化命令。 全量的原理就是遍历里所有的DB,在每个bucket,读取链表的key和value并写入dump.rdb文件(rdb.c 405)。 save命令直接调度rdbSave函...

鉴客
2011/08/31
648
0

没有更多内容

加载失败,请刷新页面

加载更多

Deepin 安装wireshark抓包工具

一、关于deepin和wireshark deepin目前已经发展到15.8了,开发Android毫无压力,在四个月的使用时间里,已经非常习惯了。目前想处理一些网络问题,因此尝试在deepin上安装一个抓包工具。dee...

IamOkay
11分钟前
0
0
Docker镜像仓库服务-Nexus

建立云原生集群系统,建立自己的私有Docker镜像仓库必不可少。一方面可以加快多节点部署容器镜像的下载速度,另一方面是为了安全(容器里存储有系统所有的信息、包括密码、数据库等等,切记不...

openthings
23分钟前
1
0
127.0.0.1 和 0.0.0.0 地址的区别

1. IP地址分类 1.1 IP地址表示 IP地址由两个部分组成,net-id和host-id,即网络号和主机号。 net-id:表示ip地址所在的网络号。 host-id:表示ip地址所在网络中的某个主机号码。 即: IP-a...

华山猛男
今天
19
0
解决Unknown host 'd29vzk4ow07wi7.cloudfront.net'. You may need to adjust the proxy settings in Gradle.

把 总项目 下的 build.gradle 中的 两个 jcenter() 用 maven{ url ‘http://maven.aliyun.com/nexus/content/groups/public/’} 代替。...

lanyu96
今天
4
0
基于redis的分布式锁

redisson提供了基于redis的分布式锁实现方式,本文就尝试了下锁的使用方式。Redisson同时还为分布式锁提供了异步执行的相关方法,第二节执行介绍。 一、可重入锁验证 同一个jvm里面同一线程的...

noob_chr
今天
14
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部