我已在项目中实现了levigo包装器,因此我可以使用LevelDB。声明是相当的样板,如下:
func NewLeveldbStorage(dbPath string) *leveldbStorage {
opts := levigo.NewOptions()
opts.SetCache(levigo.NewLRUCache(3<<30))
opts.SetCreateIfMissing(true)
log.Debugf("Entering Open")
db, err := levigo.Open(dbPath, opts); if err != nil {
log.Fatal("BOOM %v", err)
}
log.Debugf("Finished calling open")
opts.Close()
return &leveldbStorage{db:db}
}
这是返回的结构:
type leveldbStorage struct {
db *levigo.DB
}
然后我在结构上做了一些简单的GET和STORE命令,它们基本上只使用s.db.Get
和s.db.Put
。这在我的测试中运行良好,但是当我运行以下基准时:
func BenchmarkLeviDbGet(b *testing.B) {
s := storage.NewLeveldbStorage("/path/to/db")
value := "value"
uid,_ := s.Store(value)
b.ResetTimer()
for i := 0; i < b.N; i++ {
s.Get(uid)
}
此基准测试在运行时返回:
2014/10/12 21:17:09 BOOM %vIO error: lock /path/to/db/LOCK: already held by process
是否有合适的方法使用levigo / leveldb来启用多线程读取?写作怎么样?如果多线程写入不可能,我不会感到惊讶,但多线程读取似乎应该是这样。我在这里做错了什么?
答案 0 :(得分:2)
您需要关闭数据库文件或使用全局实例,不能多次打开文件,但您可以从多个goroutine访问同一个实例。