如何在golang中实现高效的内存键值存储

时间:2016-04-16 06:30:08

标签: go

我想知道golang中是否有任何包含到期且有效的包

我查了一下,这是them中的一个,但从实现的角度来看,锁定整个缓存是为了写一个不需要的条目(Check this)吗?

是否可以锁定一个条目而不是锁定整个缓存?

2 个答案:

答案 0 :(得分:1)

从你在问题中链接的同一个repo中,还有一个分片策略的实现,它应该为每个分区提供一个锁,而不是整个缓存的锁。例如,如果您决定使用4个缓存进行分区,则可以计算密钥的某些哈希的模数,并将其存储在该索引的缓存中。改进这种方法,理论上你可以使用子分区进行分片,通过二叉树分解密钥,为你提供所需的缓存(和锁定)粒度。

答案 1 :(得分:0)

仅锁定一个条目并不容易,但是你想要更有效率,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}
                }
        }
    }
}