为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
GCT1015 2022-01-04 15:44:21
我想知道 golang 中是否有任何会过期且有效的包我查了一些,这是一个他们,但是从实现的角度来看它是锁定整个缓存写入一个条目(检查这这是不对的需要)?是否可以锁定一个条目而不是锁定整个缓存?
查看完整描述

2 回答

?
子衿沉夜

TA贡献1828条经验 获得超3个赞

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


查看完整回答
反对 回复 2022-01-04
?
哆啦的时光机

TA贡献1779条经验 获得超6个赞

只锁定一个条目并不容易,但是您想要更高效,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}

                }

        }

    }

}



查看完整回答
反对 回复 2022-01-04
  • 2 回答
  • 0 关注
  • 176 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信