英文:
How to implement efficient in memory key value store in golang
问题
我想知道在Golang中是否有任何具有过期和高效性的包。
我查了一些,这是其中一个包,但从实现的角度来看,它是锁定整个缓存以写入一个条目(请查看这个),这是不必要的,对吗?
是否可能只锁定一个条目而不是整个缓存?
英文:
I would like to know are there any packages in golang that will have expiry and efficient
I checked a few, Here is one of them, But from the implementation perspective it is locking entire cache to write one entry (Check this) which is not needed right?
Is it possible to lock one entry instead of locking entire cache?
答案1
得分: 1
从你在问题中提供的同一个存储库中,还有一个分片策略的实现,它可以为每个分区提供一个锁,而不是为整个缓存提供一个锁。例如,如果你决定使用4个缓存进行分区,你可以计算关键字的哈希值的模,并将其存储在该索引处的缓存中。通过改进这个方法,你可以理论上使用子分区进行分片,通过二叉树分解关键字,以实现所需的缓存(和锁定)粒度。
英文:
From the same repo you linked in your question, there is also an implementation of sharding strategy that should provide you with a lock per partition vs a lock for the whole cache. For example if you decide to partition using 4 caches, you can compute the modulo of some hash for the key and store in the cache at that index. Refining this same method, you could in theory shard using sub-partitions, decomposing the key thru a binary tree to give you the desired caching (and locking) granularity.
答案2
得分: 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 c.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}
}
}
}
}
希望对你有帮助!
英文:
It is not easy to lock only one entry, but you wanna more efficient, a good practice in Go is to use channel to communicate with a sequential process. In this way, there is no shared variables and locks.
a simple example of this:
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}
}
}
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论