[转帖]什么是WAL?
什么是WAL?
https://www.cnblogs.com/hzmark/p/wal.html 原来数据库与消息中间件 用的是相同的模式 都是基于 顺序写的性能优于 离散写 series 强于scatter
在写完上一篇《Pull or Push》之后,原本计划这一片写《存储层设计》,但是临时改变主意了,想先写一篇介绍一下消息中间件最最基础也是最核心的部分:write-ahead logging(WAL)。
什么是WAL
"In computer science, write-ahead logging (WAL) is a family of techniques for providing atomicity and durability (two of the ACID properties) in database systems."——维基百科
在计算机领域,WAL(Write-ahead logging,预写式日志)是数据库系统提供原子性和持久化的一系列技术。
在使用WAL的系统中,所有的修改都先被写入到日志中,然后再被应用到系统状态中。通常包含redo和undo两部分信息。
为什么需要使用WAL,然后包含redo和undo信息呢?举个例子,如果一个系统直接将变更应用到系统状态中,那么在机器掉电重启之后系统需要知道操作是成功了,还是只有部分成功或者是失败了(为了恢复状态)。如果使用了WAL,那么在重启之后系统可以通过比较日志和系统状态来决定是继续完成操作还是撤销操作。
redo log
redo log称为重做日志,每当有操作时,在数据变更之前将操作写入redo log,这样当发生掉电之类的情况时系统可以在重启后继续操作。
undo log
undo log称为撤销日志,当一些变更执行到一半无法完成时,可以根据撤销日志恢复到变更之间的状态。
MySQL中用redo log来在系统Crash重启之类的情况时修复数据(事务的持久性),而undo log来保证事务的原子性。
WAL在消息中间件中的应用
WAL可以说是消息中间件的基础,也是所有存储类系统的基础。
在消息中间件中,WAL没有MySQL中那么复杂,我们只需要记redo log。消息直接存储在redo log中,只要写redo log完成了,那么消息就写入完成了:
消息写入redo log就表明持久化了
且不会出现原子性的问题,消息写入即成功,没写入即失败
存储结构
使用WAL存储数据,就需要去组织存储文件,比如MySQL的binlog文件。在消息中间件中也需要类似的形式去组织redo log,即消息的存储文件。
我们采用固定大小的存储文件,这样在索引消息的时候,只要知道偏移量,就能找到对应的存储文件。比如下面是文件大小为1024的存储文件示例:
消息被不断的追加到最新的存储文件中。
消息在文件中的存储格式大致如上:
采用二进制的格式存储消息
消息是不定长的
所以这里会需要一个结构来索引消息。索引到一条完整的消息只需要两个元素:偏移量、大小。只要有这两个元素就可以从存储日志中读取一段完整的数据(一条完整的消息)。
以上的结构是最简单的消息中间件存储的模型,虽然离真正应用到实践中还有一些距离,但是核心思想是一致的。
考虑这几个问题:
消息具体的存储协议,即存储文件中消息需要包含哪些内容
如何优化索引结构,支持消息回溯、消息过滤等功能
确定一下这几个问题的解决方案基本就是一个可以使用的消息中间件的WAL了。
Crash Recovery
上文说了redo log用于在系统Crash之后做恢复(在中间件中也直接作为数据存储),那么redo log具体我们可以如何使用它进行系统状态的恢复呢?
在消息写入的过程中,这里的状态只有一个,就是消息索引。只要消息索引构建了,那么消息就可以被消息;如果消息索引没构建,那么这条消息就是不可消费的(等价于消息没有写入)。
那么这里的恢复就是在系统Crash之后如何构建索引。
比如上图的状态是已经构建了消息0-3的索引,需要构建消息4-7的索引信息。
这个实现很简单:
消息一旦构建了索引,就记录checkpoint;checkpoint可以定期刷盘
系统恢复过程中读取checkpoint之后的消息构建索引;如果读取的消息不完整,则丢弃消息(可以采用CRC验证之类的方式来校验消息是否完成)
因为消息没有完整写入redo log的情况(写入时系统Crash了)系统并不会响应Producer消息发送成功(只有成功刷盘了才会响应成功),所以直接丢弃不完整的消息并不会对系统语义产生影响(不完整的消息没有响应Producer,也没有构建索引)。
结语
上文介绍了一下WAL,简要的描述了消息中间件存储模型和Crash Recovery,还有一些遗留的问题:
如何实现消息回溯和过滤,如何支持多tag过滤?
消息需要写文件且刷盘,如何保证写入性能?
消费时需要从文件读取消息,如何保证性能?
序列化的消息需要包含哪些属性才能完整的恢复出索引?
往期文章:
[转帖]什么是WAL?的更多相关文章
- [转帖]PostgreSQL与MySQL比较 From 2010年
PostgreSQL与MySQL比较 [复制链接] http://bbs.chinaunix.net/thread-1688208-1-1.html osdba 稍有积蓄 好友 博客 消息 论坛徽章 ...
- nginx负载均衡基于ip_hash的session粘帖
nginx负载均衡基于ip_hash的session粘帖 nginx可以根据客户端IP进行负载均衡,在upstream里设置ip_hash,就可以针对同一个C类地址段中的客户端选择同一个后端服务器,除 ...
- HBase的Write Ahead Log (WAL) —— 整体架构、线程模型
解决的问题 HBase的Write Ahead Log (WAL)提供了一种高并发.持久化的日志保存与回放机制.每一个业务数据的写入操作(PUT / DELETE)执行前,都会记账在WAL中. 如果出 ...
- HBase的Write Ahead Log (WAL) —— API与基本概念
HBase的数据写入操作,会先记录到HLog中,再真正写入到MemStore中.前者是对写入友好的格式,后者是对查询友好的格式.所以前者吞吐量更高,写入成功率大,提高了系统的可靠性,“基本”可以实现宕 ...
- [转帖]网络协议封封封之Panabit配置文档
原帖地址:http://myhat.blog.51cto.com/391263/322378
- [转帖]零投入用panabit享受万元流控设备——搭建篇
原帖地址:http://net.it168.com/a2009/0505/274/000000274918.shtml 你想合理高效的管理内网流量吗?你想针对各个非法网络应用与服务进行合理限制吗?你是 ...
- 3d数学总结帖
3d数学总结帖,以下是对3d学习过程中数学知识的简单总结 角度值和弧度制的互转 Deg2Rad 角度A1转弧度A2 => A2=A1*PI/180 Rad2Deg 弧度A2转换角度A1 => ...
- [转帖]The Lambda Calculus for Absolute Dummies (like myself)
Monday, May 7, 2012 The Lambda Calculus for Absolute Dummies (like myself) If there is one highly ...
- [转帖]FPGA开发工具汇总
原帖:http://blog.chinaaet.com/yocan/p/5100017074 ----------------------------------------------------- ...
随机推荐
- [POI2008]BLO-Blockade 割点
[POI2008]BLO-Blockade 割点 题面 容易想到用\(\text{Tarjan}\)求割点.对于非割点,会损失\(2\times(n-1)\)次访问(注意是互相访问,所以要乘2):对于 ...
- redis系列(二):数据操作
1.string类型 字符串类型是Redis中最为基础的数据存储类型,它在Redis中是二进制安全的,这便意味着该类型可以接受任何格式的数据,如JPEG图像数据或Json对象描述信息等.在Redis中 ...
- 利用前端三大件(html+css+js)开发一个简单的“todolist”项目
一.介绍 todolist,即待办事项.在windows android ios上参考微软家出的那个To-Do应用,大概就是那样的.我这个更简单,功能只有“待办” “已完成”两项,并且是在浏览器打开的 ...
- MySQL数据分析-(13)表操作补充:索引
大家好,我是jacky朱元禄,很高兴继续跟大家学习MySQL数据分析实战,今天跟大家分享的主题是表补充之索引: (一)前面课程的小节以及本节课程的逻辑梳理 在正式分享主题之前,jacky先跟大家捋顺一 ...
- MySQL数据分析-(11)表补充:数据类型
大家好,我是jacky,很高兴继续跟大家学习<Mysql 数据分析实战系列教程>,上次课程jacky讲解了表层面的增删改查,jacky说最重要的是增,增就是创建表,作为一个严谨的MySQL ...
- Git入门(待更)
github是什么? 以下截取自百度百科 github: GitHub 是一个面向开源及私有软件项目的托管平台,因为只支持 Git 作为唯一的版本库格式进行托管,故名 GitHub. GitHub 于 ...
- k8s之yaml详解
k8s之yaml详解 apiVersion: v1 #指定api版本,此值必须在kubectl apiversion中 kind: Pod #指定创建资源的角色/类型 metadata: #资源的元数 ...
- BZOJ3907网格
这东西是拿Cat思想搞得组合数学. 首先做这个需要会用网格法或折线法分析Cat的$C_{2n}^n-C_{2n}^{n-1}$是怎么来的. 网格法:假如没有限制,从(0,0)到(n,n)的方案数为$C ...
- win10设置开机开启数字锁定
windows10开机小键盘默认关闭,网上查询修改InitialKeyboardIndicators键值为2,或者80000002,经过实际测试,均无效,键值8000000002有效,是中间8个0,开 ...
- c++后台开发面试常见知识点总结(一)c++基础
指针和引用的区别 extern,const,static,volatile关键字 #define 和const的区别 关于typedef和#define; C++程序中内存使用情况分析(堆和栈的区别) ...