这篇文章将重要形容,如何经常使用我最近新开发的 WAL(Write Ahead Log)构建属于你自己的 KV存储引擎。
wal 地址:
wal,即 Write Ahead Log,通常叫做预写日志,在普通的数据库或许存储系统中,是为了预防解体复原而存在的,以传统的 LSM 和 Bitcask 存储引擎为例,数据首先进入存储引擎时,会先写到 WAL 中,而后再降级内存索引,LSM 普通是跳表,而 Bitcask 普通是哈希表,当然你也可以选用其余的内存数据结构。
这样当系统重启时,会经过重放 wal 日志来构建内存数据结构中的内容。
在 Bitcask 存储引擎中,有一个十分不凡的中央在于,预写日志 wal 和实践存储数据的日志文件,其实就是同一个文件,这样便带来一个极大的好处,那就是咱们可以间接基于 wal 构建出一个轻量、极速、便捷牢靠的 KV 存储引擎。
而在 LSM 存储引擎中,会稍微复杂点,由于其后还有 SSTable 这一大块内容,所以本文将会便捷起见,只引见下如何构建 Bitcask 存储,当然假设你在 LSM 中经常使用了 Wisckey 这样的优化技术后,也可以经常使用 wal 来存储 kv 分别之后的 Value Log 文件。
最开局想开发这个名目,其实重要是想到要重构 rosedb 和 lotusdb,而后这其中有很多重复的内容,rosedb 的数据文件可以用 wal 来存储,lotusdb 中 Memtable 对应的预写日志,和 Value Log 也可以用 wal 来存储。
由于这几种类型它们的存储格局都是一样的,即日志追加(append only)。所以我将这个公共的局部独自提取进去,构成了一个新的名目。
而后咱们再来看一下 wal 名目的大抵结构,一个 wal 实例,其实分为了多个文件,每个文件叫做一个 Segment,这个 Segment 详细有多大,是可以在进行时性能的,自动是 1GB。
Segment 文件是分为了多个旧的文件,和一个生动的文件,新写入的数据,会写到生动的 Segment 文件中。
一个 Segment 文件外部,又分为了 n 个等分的 block 块,每一个 block 块的大小是 32 KB。block 写的是变长的 chunk 数据,一个 chunk 重要是有固定的 7 字节的头部,以及其后的实践的用户存储的数据。每个 chunk 都分为了四种类型,区分是 FULL、FIRST、MIDDLE、LAST,这重要是自创了 Leveldb/RocksDB 中的 wal 的设计。
数据在写入到 wal 中后,会失掉一个 ChunkPosition,这个 Position 是形容数据在 wal 中的位置消息,你可以间接经常使用这个位置消息从 wal 中经过 Read 方法读取到写入的数据。
从前面的形容中,可以看出,wal 其实就是由多个 Segment 文件组成,支持日志追加写数据,并且可以从中读数据的一个服务。
这几天集中优化了一下 wal 的读写性能,目前的读写速度很快,并且简直不怎样占据内存。
有了这个 wal 组件之后,咱们再基于此构建一个 Bitcask 存储引擎,将会变得极端的便捷。
首先,咱们要做的就是选用一个内存数据结构,比如 B-Tree、跳表、红黑树、哈希表等等都是可以的,只需是能够存储一个 KV 值即可。
用户写入数据,实践就是先写入到 wal 中,写到 wal 之后,你会失掉一个位置消息 ChunkPosition,而后把 Key+ChunkPosition 存储到内存数据结构中即可。
而后是读数据,间接依据 Key 从内存数据结构中失掉到对应的 ChunkPosition,而后依据这个位置从 wal 中读取到实践的 Value 即可。
最后是重启数据库,须要调用 wal 中的 NewReader 方法,这个方法可以遍历 wal 中的一切数据,并前往 Key+ChunkPosition 消息,你只须要把这个数据再次寄存到内存数据结构中就可以了。
这几个重要的步骤一成功,一个最基础的 KV 存储引擎就构建起来了,当然你还可以基于此做很多的完善和优化。
好了,这就是基于 wal 这个组件来构建你自己的 KV 存储引擎的大抵流程,大家可以自己去尝试入手写一下,对自己的实战才干优化应该还是很大的。假设名目对大家有协助的话,可以给个 star 支持下哦!
本网站的文章部分内容可能来源于网络和网友发布,仅供大家学习与参考,如有侵权,请联系站长进行删除处理,不代表本网站立场,转载联系作者并注明出处:https://clwxseo.com/wangluoyouhua/9167.html