golang如何实现高效的内存键值存储
我想知道在golang有没有过期有效的包裹 我检查了一些,这里是其中之一,但从实现的角度来看,它是锁定整个缓存来写入一个不需要的条目(检查),对吗golang如何实现高效的内存键值存储,go,Go,我想知道在golang有没有过期有效的包裹 我检查了一些,这里是其中之一,但从实现的角度来看,它是锁定整个缓存来写入一个不需要的条目(检查),对吗 是否可以锁定一个条目而不是锁定整个缓存?仅锁定一个条目并不容易,但要提高效率,Go中的一个良好做法是使用通道与顺序进程通信。这样,就没有共享变量和锁 这方面的一个简单示例: type request struct { reqtype string key string val interface{}
是否可以锁定一个条目而不是锁定整个缓存?仅锁定一个条目并不容易,但要提高效率,Go中的一个良好做法是使用通道与顺序进程通信。这样,就没有共享变量和锁 这方面的一个简单示例:
type request struct {
reqtype string
key string
val interface{}
response chan<- result
}
type result struct {
value interface{}
err error
}
type Cache struct{ requests chan request }
func New() *Cache {
cache := &Cache{requests: make(chan request)}
go cache.server()
return cache
}
func (c *Cache) Get(key string) (interface{}, error) {
response := make(chan result)
c.requests <- request{key, response}
res := <-response
return res.value, res.err
}
func (c *Cache) Set(key, val string) {
c.requests <- request{"SET", key, val, response}
}
func (c *Cache) server() {
cache := make(map[string]interface{})
for req := range memo.requests {
switch req.reqtype {
case "SET":
cache[req.key] = req.val
case "GET":
e := cache[req.key]
if e == nil {
req.response <- result{e, errors.New("not exist")}
} else {
req.response <- result{e, nil}
}
}
}
}
类型请求结构{
reqtype字符串
键串
val接口{}
response chan从您在问题中链接的同一个repo中,还有一种分片策略的实现,它应该为您提供每个分区的锁,而不是整个缓存的锁。例如,如果您决定使用4个缓存进行分区,您可以计算密钥的某些哈希的模,并将其存储在该索引处的缓存中。Refini如果使用相同的方法,理论上可以使用子分区进行切分,通过二叉树分解密钥,以提供所需的缓存(和锁定)粒度。我不是自吹自擂,但我写这篇文章只是为了解决这个问题。切分的实现方式看起来不错。但我希望密钥也有到期时间,这在CMAP中是不存在的。虽然这样做有效,但它甚至比使用sync.RWMutex
我对通道的经验是,除非你有一些Decent的异步任务在网络开销(或本地计算)水平上,与内存锁相比,它们的使用性能还不够好。因此,它回到了互斥锁(以及在其实现下面的自旋锁)YMMV。我推荐的一个建议是,始终将互斥定义放在它在结构中锁定的字段之上。捕捉得好!!我没有看到分片实现,但它仅处于实验阶段:(好吧,只需分叉,导出符号,使用它,修复它并提交PR:)