让元宇宙第一股 Roblox 崩溃的 BoltDB 的使用说明

193 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 25 天,点击查看活动详情

Bolt is a pure Go key/value store inspired by Howard Chu's LMDB project. The goal of the project is to provide a simple, fast, and reliable database for projects that don't require a full database server such as Postgres or MySQL.

bolt 是一个简单的kv数据库,使用极其简单,目前github项目处于archive 状态。

数据库连接

package main

import (
	"log"

	"github.com/boltdb/bolt"
)

func main() {
	// 文件不存在,会新建文件
	db, err := bolt.Open("sai.db", 0600, nil)
	if err != nil {
		log.Fatal(err)
	}
	defer db.Close()

	...
}

事务

// 读写
err := db.Update(func(tx *bolt.Tx) error {
	...
	return nil
})

// 只读,里面只能进行读取操作
err := db.View(func(tx *bolt.Tx) error {
	...
	return nil
})

常用操作

创建一个bucket【可以理解成一个table】

b, _ := tx.CreateBucketIfNotExists([]byte("sai0556"))

新增数据

b.Put([]byte("a"), []byte("11"))
b.Put([]byte("b"), []byte("22"))

取数据

v := b.Get([]byte("a"))
fmt.Printf("The a is: %s\n", v)

删除

b.Delete([]byte("a"))

游标遍历

/*
First()  Move to the first key.
Last()   Move to the last key.
Seek()   Move to a specific key.
Next()   Move to the next key.
Prev()   Move to the previous key
*/
c := b.Cursor()
for k, v := c.First(); k != nil; k, v = c.Next() {
    fmt.Printf("key=%s, value=%s\n", k, v)
}

// ForEach 遍历
b.ForEach(func(k, v []byte) error {
    fmt.Printf("key=%s, value=%s\n", k, v)
    return nil
})

删除bucket

tx.DeleteBucket([]byte("sai0556"))

使用是不是非常简单,自己有在项目中使用到,当个 kv 存储工具蛮好用。

注意

使用需要注意以下几点:

  • 只读 View 中,不能使用编辑、删除、新增等写操作,会产生错误
  • 因为底层使用了读写锁,进行写操作,要尽可能快,更不要开启长事务,会造成阻塞,影响性能(我猜的坑)
  • 生产环境慎用,忘了 Roblox 事件吗?

题外话

想必很多人听说 BoltDB 是因为去年元宇宙第一股 Roblox 的事件,究其原因是因为使用的 consul 里面使用的BoltDB,其中部分设计糟糕而引发的故障,但不得不说,引入开源第三方库是需要注意的,尤其是在升级版本的时候。我的建议是:

  1. 核心代码尽量不能引用第三方库,至少不能是黑盒状态的代码
  2. 如果非用不可,fork 一份,自行维护合并更新
  3. 当你技术不够的时候,使用活跃度较高的库,至少社区有人能帮你解答
  4. 注意代码安全性

更多

更多使用说明可参考: