一种更为高效的WAL的实现方式

前言


在分布式存储系统的服务一致性实现中,WAL是其中经常被使用到的一个关键的数据文件。它可以有效地记录每一次的系统变更记录,而且还能够确保系统的异常退出恢复。不过本文笔者并不打算阐述WAL的与Master/Follower节点之间的合作原理,而是打算专门来聊聊WAL的写出方式。在通常的实现中,系统写WAL时为了避免每次的操作都执行一次写磁盘的操作,一般会采用增加缓冲区的方式。等缓冲区慢了,再执行一次flush磁盘的操作。笔者本文将要阐述一种更为高效的WAL写出方式。

高效WAL的实现方式

在Apache Ratis项目中,实现了一种更为高效的WAL机制,下面笔者结合其内部实现进行阐述。在保留写操作时缓冲区的设置外,主要在以下几点上做了优化设计:

  • 写WAL时进行了异步处理,而不是同步式的方式。异步式的方式可以缩短调用方的响应延时,有效提高WAL的throughput。在Apache Ratis的内部实现中,基于的原理是新增一个worker线程,一个FIFO的runnable执行队列,调用方在执行例如append log记录时,则会往这个队列里增加一个task任务。随后worker线程将会从队列拿到最新的task然后执行。在WAL文件的写入过程中,一个log文件的状态变化如下所示:

    Open(InProgress file) —(finalize operation)— > Close —> start new Open file

  • Log Cache的引入。Log Cache的作用是为了加速客户端对于WAL日志结果的查询操作。这里的Cache不仅仅只存储部分少数的Log记录,而还有有可能是整个Log file的记录数。这样可以有效避免频繁地进行WAL Log file的文件读取操作了。因此这里的Cache需要有自己的eviction policy来进行旧的或无人访问记录的清除。

高效WAL实现过程图


以下是高效WAL实现过程图:
在这里插入图片描述
上述图中apply log到StateMachine的步骤可以理解为是系统进行了实际的请求操作处理,进行了状态的更新,例如元数据更新了等等。

发布了373 篇原创文章 · 获赞 403 · 访问量 203万+

猜你喜欢

转载自blog.csdn.net/Androidlushangderen/article/details/99896409