
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

WAL文件管理优化
先看V1中的WAL文件管理,这个阶段的实现整体还比较粗糙,没有完善的Write-Ahead-Log的概念,目录也叫做Log。
Fig 4.2.1 V1中Log存储编码和格式

V1中Log每条记录格式都是两行,前一行为数据长度,后一行为Protobuf编码的日志记录。V2开始WAL日志格式更紧凑,同时每条记录都有对应的crc字段,数据更可靠。
工程上不可能让这样的Log无休止地增长,V1中的解决方案是随着Snapshot的时机回收一部分日志,如Fig 4.2.2所示。
Fig 4.2.2 V1中截断历史日志实现

V1中的Log只有一个文件,显然是一种“把所有鸡蛋放在一个篮子里”的策略,风险很大。一旦这个Log文件因为各种原因损坏,那么这个节点就无法恢复了。
V2开始Log开始有规范的管理,进入了多个WAL文件分片存储阶段,当前正在读写的WAL文件达到64MB后,文件写入流会被切换到一个新的文件,可靠性和性能都有显著提升:
· 数据分片保存,就算损坏也仅仅损失了64MB日志
· 每次不需要对老文件作覆盖操作,新的日志也不会因为覆盖失败(权限不够)一直不成功
· 不需要回收历史日志,一旦日志分片保存,只需删除过期的日志文件即可
V3这部分也没有明显变化,仅仅对WAL文件分片部分的逻辑进行了局部的重构。
Fig 4.2.3 V2开始的WAL分片

每次写入时检查一下当前的文件大小,超过64MB就截断并切换到新的文件,切分文件的过程也比较容易理解:
· 创建.tmp文件,写入crc校验结果、Metadata和集群的状态信息
· 将tmp文件重命名为正式的WAL文件
· 将节点的WAL日志写入流切换到新的WAL文件