go 语言 kv 存储引擎 lotusdb 2.0 重磅发布! | go 技术论坛-金年会app官方网

经过差不多两个月的重构,在社区小伙伴的共同协作努力下,lotusdb v2.0.0版本正式发布!

lotusdb 项目地址:


lotusdb 是用 go 语言编写的 kv 数据库,它采用 kv 分离的思想,融 lsm tree 和 b tree 存储模型为一体,适合大规模的 kv 数据存储,相较于 go 语言领域知名的 kv 存储项目 badger 和 bbolt,lotusdb 具有更先进的设计架构。

这次我们通过两个月的重构,将 lotusdb 原来 v1 版本的代码基本上重新实现了一遍,目的在于提高简洁度。

lotusdb 的整体架构实现了全新升级,目的在于提升读写和压缩性能,下面是之前 v1 版本的架构图:

这是重构后的 v2 版本的架构图:

相对于 v1 版本,v2 版本主要有以下更新:

  • 新版本的所有磁盘存储(包括预写日志 wal 和 value log)均直接采用 wal 组件(
  • 新版本通过对 key 哈希分片的方式构建多个 index 和 value log 对象,实现了 index 和value log 的并发读写,读写和压缩性能相对于 v1 提升了 2~3 倍,这也是本次重构架构上最大的更新
  • todo:另一大重要更新是将会引入新的基于磁盘的 hash 索引,这样 lotusdb 将会支持磁盘 btree 和 hash 两种类型的索引,满足更多样化的场景(预计在下一次 release 发布)
  • 新版本舍弃了 column family(cf) 的设计,目的在于使架构更加简洁,原来跨 cf 的操作并不能保证原子性,如果后续有需求的话将会重新设计这个 feature

毫不夸张的说,这是目前 go 语言领域架构最先进的 kv 存储引擎项目,其优势主要体现在:

  • 结合了 lsm 和 b 树存储模型的优点,b 树读性能稳定,而 lsm 写吞吐高,lotusdb 在这基础上做了一个巨大的改动,就是采用 kv 分离的思想,完全舍弃掉 lsm 中的 sst 文件,改由 b 树来存储索引,而 value 存放则参考了 wisckey 和 bitcask 模型的设计,以追加写的方式存储到单独的 value log 文件中,充分利用顺序 io 的优势
  • 更加均衡和快速的读/写性能,写入 lotusdb 的数据不需要在磁盘上排序,追加写的 value log 设计在写入过程中减少了磁盘磁头的移动,因此即便是完全无序的数据,lotusdb 依然能够保持较高的吞吐量。同时 lotusdb 的读写性能更加均衡,而不会像bbolt 那样读写性能差距极大,适合读写都非常频繁的业务场景
  • 比典型的 lsm 低得多的读放大,lotusdb 采用 kv 分离的思路,从 b 树中获取 key 对应 value 在磁盘中的存储地址后,即可直接一步读取 value 数据,显著降低了传统 lsm 存储模型带来的读放大问题
  • 更大规模的数据存储,和 lotusdb 的姊妹项目 rosedb 相比,lotusdb 是一个基于磁盘索引的 kv 存储引擎,而 rosedb 是 bitcask 存储模型全内存索引,因此数据存储规模基本不受到内存大小的影响,因此更加适合大规模的数据存储
  • 支持崩溃恢复,lotusdb 实现了 wal 机制,在将 kv 数据刷盘前就将事务日志进行持久性存储,数据库崩溃后依然能够从 wal 中读取事务日志,保证事务的原子性
  • 数据并发式刷盘 lotusdb 通过将 key 进行哈希分片的机制,建立多个 index 和 value log 对象,每一组 index & value log 对象对应一个数据片,当 memory table 中的数据需要刷盘时,多个对象可以通过并发的方式实现刷盘,大大提升了刷盘的吞吐量

以下是 lotusdb 的简单使用示例,大家可以上手体验!

package main
import "github.com/lotusdblabs/lotusdb/v2"
func main() {
    // 指定设置
    options := lotusdb.defaultoptions
    options.dirpath = "/tmp/lotusdb_basic"
    // 打开数据库
    db, err := lotusdb.open(options)
    if err != nil {
        panic(err)
    }
    defer func() {
        _ = db.close()
    }()
    // 写入键值对
    key := []byte("kv store engine")
    value := []byte("lotusdb")
    putoptions := &lotusdb.writeoptions{
        sync:       true,
        disablewal: false,
    }
    err = db.put(key, value, putoptions)
    if err != nil {
        panic(err)
    }
    // 读取键值对
    value, err = db.get(key)
    if err != nil {
        panic(err)
    }
    println(string(value))
    // 删除键值对
    err = db.delete(key, putoptions)
    if err != nil {
        panic(err)
    }
    // 启动value log压缩
    err = db.compact()
    if err != nil {
        panic(err)
    }
}

致谢

在 lotusdb 的重构过程中,非常感谢社区的各位小伙伴的参与和积极贡献,特别是 @燕小七 和 @akiozihao 表现最为积极活跃,为 lotusdb 2.0 的重构做了很多工作,再次表示感谢,也希望能够继续参与。

同时 @燕小七 同学成为了 lotusdb 的第一位 committer,后续我们希望能够培养更多的 committer 和 maintainer,充分发挥社区的作用,共同打造和完善 lotusdb 这个最先进的 kv 存储引擎!

同时也非常欢迎大家能够参与进来,目前我们只是发布了第一个版本,后续将会持续迭代,能够让大家发挥的空间巨大,感兴趣的可以加我微信私聊,我会将你拉到开发者群当中。

本作品采用《cc 协议》,转载必须注明作者和本文链接
roseduan
讨论数量: 2

一直都在用bardgedb,这个能在线上使用么?主要是事务要绝对安全。

1年前
roseduan (楼主) 1年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!
网站地图