boltdb
boltdb
是一款golang实现的嵌入式K-V存储引擎。在boltdb的源码中的doc.go
对其有一个简要的说明。
其提供事务、ACID语言、无锁MVCC支持。数据提供零拷贝、B-TREE索引。其主要设计源于Howard Chu的LMDB。
持久化
boltdb
采用一个单独的文件作为持久化存储。其将不同的文件部分划分为不同的page,不同的page
存储不同类型的数据(meta、key、value)等。当经过反复的增删改查后,文件中可能出现没有数据的
部分。此时boltdb
并不打算搬移数据、截断文件来将多余的空间返还给操作系统。而是将这些部分,
加入内部的FreeList
来维护,当有新的数据写入时,复用这些空间。因此从用户视角来看,boltdb
的持久化文件只会增大,而不会因为数据的删除而减少。
boltdb
在写入数据时,为了提高效率,采用unsafe
的方法直接获得相关struct
的系统内存layout,
而没有使用一些序列化工具。因此持久化文件里记录的数据格式是操作系统相关的。因此不能将一个大端
系统中的持久化文件复制到一个小端系统中使用。
由于boltdb
采用B-TREE索引,会带来随机写入,所以在有写入瓶颈的场景中,只能通过使用SSD来提高。
当用户写入一个key-value对时,boltdb
根据key写入相关的B-TREE索引指定的文件偏移量中去。
其零拷贝的特性主要体现在它将持久化文件以只读模式通过mmap
映射到内存空间中,然后通过索引
找到内存中key对应的value所指向的空间,然后将这段内存返回给用户。因此在database存储数据比较多
时,可能会显示程序的内存使用量很高。boltdb
在做文件mmap
映射时的策略比较简单,即将文件整体映
射到内存空间中,完全利用操作系统的虚拟内存空间与物理内存动态映射、换出的机制,而没有去做动态的
映射变更,在地址空间比较小的32bit系统中可能会带来一些限制。
用只读默认来映射也保护了持久化文件,防止用户程序出现内存越界,将持久化文件污染。
这也带来一个问题,boltdb
返回的内存切片是一段只读的内存,用户不能对其进行修改。而且该内存的生命周期
只存在于相关事务持续周期内。