youbbs
youbbs
1807 0 0

对 youdb 的锁做了一点改进

前几天因为对 youdb 做密集型写操作的速度不满意,短时间又不想对 youdb 改动,就利用现成的 sdb (底层是 leveldb )换掉。

现在对 youdb 作了一点优化,写性能也很好了。

$ go run main.go 
userMap len 4657
oauthMap len 4833
nodeMap len 50
topicMap len 3050
viewMap len 3169
uaMap len 473
urlMd5Map len 2661
done 1.003970444s

上面是从旧网站导入数据的 log ,使用 leveldb 耗时 1.421254603s (参见 https://youbbs.org/t/3276 )

这改进也使数据库的操作方式改变。

原来是:

db.Hset("test", []byte("k"), []byte("v"))
db.Hget("test", []byte("k"))

调整后要这么写:

db.Update(func(tx *bolt.Tx) error {
    db.Hset(tx, "test", []byte("k"), []byte("v"))
    db.Hget(tx, "test", []byte("k"))
    return nil
})

多传一个参数 tx,确实不方便,可以在这一层避免并发出错,但在底层 boltdb 还是加了锁,单线协程优势是批量读写(整块加锁),多协程就没有体现出并发优势 🔒🔒🔒

对比

原来是单条操作完成一个事务,修改后是多条操作一个事务。改进后的好处是避免频繁加锁解锁,极大提高写速度。就拿自己自己网站数据的导入,写9万多条 key/value 数据,原来用 45 分钟,改进后只用 1 秒多一点点点。同时又能对事务的控制,中途发生错误即可回滚。

原来的操作方式是一步一个坑,简洁明了,在非密集读写操作的场合还很方便。所以此次改进另起新库 https://github.com/ego008/udb

0

See Also

Nearby


Discussion

Login Topics