Pogreb Embedded key-value store for read-heavy workloads written in Go
特点:
- 100% Go 语言实现
- 针对快速随机查找和不频繁的批量插入进行了优化。
- 可以存储大于内存的数据集。
- 内存使用率低。
- 所有DB方法对于多个goroutine并发使用都是安全的。
这个数据库诞生的目的:
我需要一个可以将键映射到具有以下要求的值的存储:
- 键的数量很大,我无法将这些项保存在内存中(这需要切换到更昂贵的服务器实例类型)。
- 低延迟。如果可能的话,我想避免网络开销。
- 我需要每天重建一次映射,然后以只读模式访问它。
- 顺序查找性能并不重要,我只关心随机查找性能。
有很多开源的 K/V 数据库 —— 最流行的是 LevelDB、RocksDB 和 LMDB。此外,用 Go 语言实现的,例如Bolt、goleveldb 和 BadgerDB。
我尝试在生产中使用 LevelDB 和 RocksDB,但不幸的是,观察到的结果不符合性能要求。
随机读性能
https://github.com/akrylysov/pogreb
示例
package main
import (
"log"
"github.com/akrylysov/pogreb"
)
func main() {
db, err := pogreb.Open("pogreb.test", nil)
if err != nil {
log.Fatal(err)
return
}
defer db.Close()
// Insert a new key-value pair.
if err := db.Put([]byte("testKey"), []byte("testValue")); err != nil {
log.Fatal(err)
}
if err := db.Put([]byte("k2"), []byte("testValue")); err != nil {
log.Fatal(err)
}
if err := db.Put([]byte("k5"), []byte("testValue")); err != nil {
log.Fatal(err)
}
if err := db.Put([]byte("k1"), []byte("testValue")); err != nil {
log.Fatal(err)
}
if err := db.Put([]byte("k2"), []byte("testValue22")); err != nil {
log.Fatal(err)
}
// Retrieve the inserted value.
val, err := db.Get([]byte("testKey"))
if err != nil {
log.Fatal(err)
}
log.Printf("%s", val)
// Iterate over items.
it := db.Items()
for {
key, val, err := it.Next()
if err == pogreb.ErrIterationDone {
break
}
if err != nil {
log.Fatal(err)
}
log.Printf("--- %s %s", key, val)
}
}
key 存储并不是有序的,如上例遍历,key 出现的顺序是首次保存的顺序:
2009/11/10 23:00:00 --- k2 testValue22
2009/11/10 23:00:00 --- k5 testValue
2009/11/10 23:00:00 --- k1 testValue
如果要排序,可以通过人设有序 key。
限制
由于考虑到性能,作者设计时使用 Uint32
贯穿整个架构,所以有个硬性限制是,keys 总数不能超过 42亿 条
缺点
由于数据结构特点,产生的数据文件特别大,实测中 150MB 的纯数据,该数据库生成的文件大小 2.2GB,而其它同类
- 94M ./ldb (leveldb)
- 224M ./bdb (boltdb)
0
See Also
Nearby
- 上一篇 › pdfcpu: GO 语言实现写的 PDF 处理器
- 下一篇 › Kill TechToolProDaemon