DevilKing's blog

冷灯看剑,剑上几分功名?炉香无需计苍生,纵一穿烟逝,万丈云埋,孤阳还照古陵

0%

bolt-内嵌kv存储

repo

However, this limited scope also means that the project is complete.

more featureful version repo

关于transactions的手动实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// Start a writable transaction.
tx, err := db.Begin(true)
if err != nil {
return err
}
defer tx.Rollback()

// Use the transaction...
_, err := tx.CreateBucket([]byte("MyBucket"))
if err != nil {
return err
}

// Commit the transaction and check for error.
if err := tx.Commit(); err != nil {
return err
}

使用bucket部分

这里面比较有意思的是:通过seek()部分操作

  • prefix scans
  • range scans
  • foreach

天然支持database backups

comparison with other databases

Postgres, MySQL, & other relational databases

sql

Bolt accesses all data by a byte slice key. This makes Bolt fast to read and write data by key but provides no built-in support for joining values together. Bolt runs as a library included in your application so all data access has to go through your application’s process. This brings data closer to your application but limits multi-process access to the data.

LevelDB, RocksDB

their underlying structure is a log-structured merge-tree (LSM tree). An LSM tree optimizes random writes by using a write ahead log and multi-tiered, sorted files called SSTables

Bolt uses a B+tree internally and only a single file.

If you require a high random write throughput (>10,000 w/sec) or you need to use spinning disks then LevelDB could be a good choice. If your application is read-heavy or does a lot of range scans then Bolt could be a good choice.

One other important consideration is that LevelDB does not have transactions. It supports batch writing of key/values pairs and it supports read snapshots but it will not give you the ability to do a compare-and-swap operation safely. Bolt supports fully serializable ACID transactions.(事务上的支持)

LMDB

Bolt was originally a port of LMDB so it is architecturally similar. Both use a B+tree, have ACID semantics with fully serializable transactions, and support lock-free MVCC using a single writer and multiple readers.

on safe actions

on api, LMDB requires a maximum mmap size when opening an mdb_env whereas Bolt will handle incremental mmap resizing automatically

conclusion

  • Bolt is good for read intensive workloads.
  • Bolt uses a B+tree internally so there can be a lot of random page access
  • Bulk loading a lot of random writes into a new bucket can be slow as the page will not split until the transaction is committed. 在一个事务里尽量是连续性的操作
  • The data structures in the Bolt database are memory mapped so the data file will be endian specific
  • Because of the way pages are laid out on disk, Bolt cannot truncate data files and return free pages back to the disk. Instead, Bolt maintains a free list of unused pages within its data file. These free pages can be reused by later transactions. 关于bolt的reuse特性