【发布时间】:2012-07-11 01:12:59
【问题描述】:
问题 1
我正在为我的服务器构建/搜索 RAM 内存缓存层。它是一个简单的 LRU 缓存,需要处理并发请求(均 Gets an Sets)。
我发现 https://github.com/pmylund/go-cache 声称是线程安全的。
就获取存储的接口而言,这是正确的。但是如果多个 goroutine 请求相同的数据,它们都在检索指向同一内存块的指针(存储在接口中)。如果任何 goroutine 更改了数据,这将不再是非常安全的。
有没有可以解决这个问题的缓存包?
问题 1.1
如果问题 1 的答案是 否,那么建议的解决方案是什么?
我看到两个选项:
替代方案 1
解决方案: 将值存储在带有 sync.Mutex 的包装结构中,这样每个 goroutine 都需要在读取/写入数据之前锁定数据type cacheElement struct { value interface{}, lock sync.Mutex }
缺点: 缓存不知道对数据所做的更改,甚至可能已将其从缓存中删除。一个 goroutine 也可能锁定其他 goroutine。
备选方案 2
解决方案:制作数据副本(假设数据本身不包含指针)
缺点: 每次执行缓存 Get 时分配内存,更多垃圾回收。
对不起,多部分问题。但您不必全部回答。如果您对问题 1 有一个好的答案,那对我来说就足够了!
【问题讨论】:
-
在缓存中存储指针会丢失缓存点。在备选方案 1 中;如果要使用互斥锁,则互斥锁应位于商店级别,而不是入门级别。
标签: caching interface thread-safety go lru