第四十章 LevelDB与BoltDB

作者:李骁

LevelDB 和 BoltDB 都是k/v非关系型数据库。

LevelDB没有事务,LevelDB实现了一个日志结构化的merge tree。它将有序的key/value存储在不同文件的之中,通过db, _ := leveldb.OpenFile("db", nil),在db目录下有很多数据文件,并通过“层级”把它们分开,并且周期性地将小的文件merge为更大的文件。这让其在随机写的时候会很快,但是读的时候却很慢。

这也让LevelDB的性能不可预知:但数据量很小的时候,它可能性能很好,但是当随着数据量的增加,性能只会越来越糟糕。而且做merge的线程也会在服务器上出现问题。

LSM树而且通过批量存储技术规避磁盘随机写入问题。 LSM树的设计思想非常朴素,它的原理是把一颗大树拆分成N棵小树, 它首先写入到内存中(内存没有寻道速度的问题,随机写的性能得到大幅提升),在内存中构建一颗有序小树,随着小树越来越大,内存的小树会flush到磁盘上。磁盘中的树定期可以做merge操作,合并成一棵大树,以优化读性能。

BoltDB会在数据文件上获得一个文件锁,所以多个进程不能同时打开同一个数据库。BoltDB使用一个单独的内存映射的文件(.db),实现一个写入时拷贝的B+树,这能让读取更快。而且,BoltDB的载入时间很快,特别是在从crash恢复的时候,因为它不需要去通过读log去找到上次成功的事务,它仅仅从两个B+树的根节点读取ID。

BoltDB支持完全可序列化的ACID事务,让应用程序可以更简单的处理复杂操作。

BoltDB设计源于LMDB,具有以下特点:

  • 直接使用API存取数据,没有查询语句;

  • 支持完全可序列化的ACID事务,这个特性比LevelDB强;

  • 数据保存在内存映射的文件里。没有wal、线程压缩和垃圾回收;

  • 通过COW技术,可实现无锁的读写并发,但是无法实现无锁的写写并发,这就注定了读性能超高,但写性能一般,适合与读多写少的场景。

  • 最后,BoltDB使用Golang开发,而且被应用于influxDB项目作为底层存储。

LMDB的全称是Lightning Memory-Mapped Database(快如闪电的内存映射数据库),它的文件结构简单,包含一个数据文件和一个锁文件. LMDB文件可以同时由多个进程打开,具有极高的数据存取速度,访问简单,不需要运行单独的数据库管理进程,只要在访问数据的代码里引用LMDB库,访问时给文件路径即可。

让系统访问大量小文件的开销很大,而LMDB使用内存映射的方式访问文件,使得文件内寻址的开销非常小,使用指针运算就能实现。数据库单文件还能减少数据集复制/传输过程的开销。

40.1 LevelDB

Go语言LevelDB的实现我们使用 github.com/syndtr/goleveldb/leveldb 包,通过go get命令下载该包后在程序中导入。

goleveldb主要有Get(),Put()等方法,可进行key/value的读取和写入,可进行事务批量Put()插入key,Delete()删除某个key。

Leveldb比较突出的问题是在读操作上,在大量key的情况下可能成为性能的瓶颈,我们可以根据场景来选择使用。下面是我们进行的几种数量级别的基准测试数据:

BenchmarkWrite-4 100000 14541 ns/op BenchmarkRead-4 100000 13094 ns/op

BenchmarkWrite-4 500000 12724 ns/op BenchmarkRead-4 500000 17002 ns/op

BenchmarkWrite-4 1000000 13355 ns/op BenchmarkRead-4 1000000 20610 ns/op

BenchmarkWrite-4 3000000 15644 ns/op BenchmarkRead-4 3000000 22742 ns/op

我们可以看到随着key的数量的增加,读的性能明显地下降,而写的性能则不受影响。

40.2 BoltDB

Go语言BoltDB的实现我们使用 github.com/boltdb/bolt 包,通过go get命令下载该包后在程序中导入。

BoltDB中存储比较重要的概念是bucket,存取操作之前都需要指定bucket,如果读数据时指定bucket不存在,则会panic。

BoltDB的性能测试这里就不再做阐述,和LevelDB正好相反,它在写性能上存在瓶颈,而读性能上非常有优势,这两者我们需要根据场景来选择使用。

目录

第三十九章 Mysql数据库

第四十一章 网络爬虫

本书《Go语言四十二章经》内容在github上同步地址:https://github.com/ffhelicopter/Go42

虽然本书中例子都经过实际运行,但难免出现错误和不足之处,烦请您指出;如有建议也欢迎交流。 联系邮箱:[email protected]

Last updated

Was this helpful?