快速理解 WAL 机制,架构师必备技能!「建议收藏!!」

Posted 魏小言

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了快速理解 WAL 机制,架构师必备技能!「建议收藏!!」相关的知识,希望对你有一定的参考价值。


  WAL 机制,是个伟大的设计,在不同的系统、组件中,都存在它的身影。
  WAL 的分析了解,也是你在架构设计道路上,必备的技能之一。

  下面来简单唠唠:


什么是 WAL 机制

  WAL 全称为,Write Ahead Log ,译为进行写操作前先写日志。

WAL 应用场景

  那么 WAL 是用来做什么的呢?

  WAL 最早/常出现的场景数据库操作中,解决两个问题。

1、提升数据写磁盘效率。将数据直接随机写的行为,调整为,内存缓存数据之后进行批量 或 有序写。
2、进行数据恢复,提升系统鲁棒性。记录了数据行为信息,重播可复原数据。

WAL 磁盘中具象结构

  在磁盘中,WAL 一般为以下目录结构

在这里插入图片描述
  上图包含两个数据文件「000004、000005」、和一个检查点checkpoint.000003。
  每个文件大小一般在128M左右,具体存储数据格式有具体业务决定。


  结合上一篇 普罗米修斯?古希腊泰坦之神?异形?不,新一代企业级监控组件—Prometheus!中提到的 WAL 机制,下面详细讲解一下关于 WAL 结构中各部分的设计。

  在 Prometheus 中,数据写入利用到了 WAL 。TS 数据指标首先写入内存结构「 head 」,之后写入 WAL 中。
  在 head 中数据会按照文件配置规格进行文件拆分,形成不同的 chunk 文件,相应的操作与文件对应,WAL 作为记录数据写入机制,也会形成对应的几个文件,图中可以看到「000001、000002、000003、000004、000005」。
  当 head 中数据规模在 chunkRange 的2/3时「一般默认chunkRange为2h」,就会将chunkRange中的 chunks 进行持久化入磁盘,同时会进行WAL截断。


WAL 截断

  为什么要进行 WAL 截断呢?

  • WAL 是对内存中数据的记录,需要与内存数据保持相似一致。
  • WAL 不可以持续扩张,资源有限且重播的时候没必要。

  在 head 持久化, WAL 进行截断的时候会进行检查点 checkPoint 的建立,完成之后进行截断。


WAL 检查点 checkPoint

  由于在写操作可能是无序的,在文件拆分时,不同的 chunk 可能含有 head 中后面还会用到的数据。比如,在 series 中,相同的 label 是只存储一次的,不同时间到 sample 只会存储 label 的引用,故在 WAL 文件中的数据可能存在拉扯状态。
   checkPoint 会按照 WAL 文件顺序进行便利,删除不在 head 中的 series 的所有 series 记录;删除时间T之前的所有 sample ;删除T之前时间范围内的所有逻辑删除记录。
  如上图中数据结构目录就是,head 的 000001、000002、000003文件已经进行了持久化, WAL 进行了截断,且形成了检查点 checkpoint.000003 。

  在进行重播时,从最后一个检查点开始依次遍历记录(与它关联的最大数字的检查点是最后一个检查点)。对于checkpoint.X,X告诉我们需要从哪个WAL段继续重放,即X + 1。因此,在上面的示例中,在重播checkpoint.000003之后,我们从WAL段000004继续重播。

Q&A

1、在 checkPoint 中为什么要记录最后检查点呢?「000003 为此次 WAL 截断的最后检查点」

  因为创建检查点和 WAL 截断不是原子的。在两者之间可能发生任何事情,所以记录检查点,进行跟踪,防止出现数据重播断片问题。

附录

一天一个小技巧,偷偷超越隔壁老大哥!

欢迎关注收藏,加入群聊【编程技术交流分享Q群717647116】,微信群请私信博主添加!

以上是关于快速理解 WAL 机制,架构师必备技能!「建议收藏!!」的主要内容,如果未能解决你的问题,请参考以下文章

你知道系统模块之间如何聊天吗?——摊牌了,不装了,就是这样聊......「建议关注收藏!!架构师养成必备」

你知道系统模块之间如何聊天吗?——摊牌了,不装了,就是这样聊......「建议关注收藏!!架构师养成必备」

程序员必备技能之SpringBoot的自动装配原理,很详细,建议收藏!!!

程序员必备技能之SpringBoot的自动装配原理,很详细,建议收藏!!!

走向架构师必备的技能

必备技能~Java编程使用Junit实现接口单元测试,快速实现接口全覆盖(建议收藏)