关于golang:用-Go-语言造了一个全新的-kv-存储引擎

14次阅读

共计 2180 个字符,预计需要花费 6 分钟才能阅读完成。

经验了大略 4 个月的打磨,LotusDB 的第一个 release 版本终于公布了,我看了下,有 200 屡次 commit(靠近 rosedb 一年多的 commit 次数了)。

我的项目地址:https://github.com/flower-cor…

有了 rosedb 在 bitcask 模型上的实际之后,以及本人在存储这方面的一些教训积攒,去年底的时候,在下班路上忽然想到的一个 idea,让我有了做一个新的 kv 存储引擎的想法。

有了想法之后便是验证,因为其实心里还是没谱,我又在 Github 上翻了翻,并没有同类型的实现。起初又找一些大佬沟通了下,证实我的想法是可行的。

这期间还发现了 Usenix Fast 上的一篇对于优化 LSM 的论文,发现论文的内容跟我的 idea 十分相似,这算是又多了一个理论依据,于是便决定开干了。

感兴趣的能够参考下论文,叫做 SLM-DB,地址:https://www.usenix.org/confer…

家喻户晓,数据存储引擎,目前最支流的两种模型是 B+ 树和 LSM 树,B+ 树在关系型数据库例如 Mysql 中利用比拟宽泛,而 LSM 的典型代表 rocksdb 也是大多数分布式系统数据落盘的首选。

B+ 树读性能稳固,而 LSM 写吞吐高,LotusDB 在这根底上做了一个微小的改变,就是齐全舍弃掉 LSM 中的 SST 文件,改由 B+ 树来存储索引,而 value 寄存则参考了 Wisckey 和 bitcask 模型的设计,存储到独自的 value log 文件中。

LotusDB 是对 LSM 和 B+ 树的劣势联合,目前并没有同类型的实现,咱们应该是第一个吃螃蟹的人。

LotusDB 的架构图如下:

前台的写入和 LSM 完全一致,先写 wal 再写 memtable。

而读取则会从 memtable 开始,如果 memtable 找到了,间接返回;没找到的话则从 B+ 树中查问索引,而后依据索引信息到 value log 中获取 value。

大家能够先理解个大略,后续我会出一个残缺的 《LotusDB 设计与实现》 系列文章,全面解析 LotusDB 的架构细节以及代码实现,目前曾经写了几篇待发布,欢送关注公众号的后续更新:

再来看看 LotusDB 提供的一些根本接口,目前实现了根底的 Put、Get、Delete 接口,并且反对 Column Family(借鉴于 rocksdb),以及 value log 的主动 GC 回收。

简略的应用办法如下:

package main

import (
    "github.com/flower-corp/lotusdb"
    "io/ioutil"
    "time"
)

// basic operations for LotusDB:
// put
// put with options
// get
// delete
// delete with options
func main() {path, _ := ioutil.TempDir("","lotusdb")
    opts := lotusdb.DefaultOptions(path)
    db, err := lotusdb.Open(opts)
    if err != nil {panic(err)
    }
    defer db.Close()

    // 1.----put----
    key1 := []byte("name")
    err = db.Put(key1, []byte("lotusdb"))
    if err != nil {// ...}

    key2 := []byte("feature")
    // 2.----put with options----
    writeOpts := &lotusdb.WriteOptions{
        Sync:      true,
        ExpiredAt: time.Now().Add(time.Second * 100).Unix(),}
    err = db.PutWithOptions(key2, []byte("store data"), writeOpts)
    if err != nil {// ...}

    // 3.----get----
    val, err := db.Get(key1)
    if err != nil {// ...}
    if len(val) > 0 {// ...}

    // 4.----delete----
    err = db.Delete(key1)
    if err != nil {// ...}

    // 5.----delete with options----
    deleteOpts := &lotusdb.WriteOptions{
        Sync:       false,
        DisableWal: true,
    }
    err = db.DeleteWithOptions([]byte("dummy key"), deleteOpts)
    if err != nil {// ...}
}

目前自认为 LotusDB 的代码品质比之前的 RoseDB 好多了,单元测试更加齐备,正文清晰,代码也更加简洁标准,如果你是 Go 老手,或者筹备学习 Go,也可能把我的项目当做练习素材,本人对照着来学习。

当然咱们的愿景还是打造一个可能在生产环境中理论落地的存储引擎,目前的版本只是一个开始,后续还会有十分多的工作,包含但不限于:

  • batch 操作,保障原子性
  • 多个 Column Family 保障原子性
  • 基于 SSI 的事务
  • Iterator 迭代器
  • 数据压缩
  • 数据备份
  • index 的决裂

如果大家在应用或者学习的过程中,有任何问题都能够微信分割我:

感觉有帮忙的话,欢送 给我的项目点个 star 反对下

我的项目地址:https://github.com/flower-cor…

正文完
 0