我的问题有点类似于问题https://github.com/golang/groupcache/issues/3。
我有一个地图,目前在单个实例上的 go 应用程序的 RAM 中进行管理。 我想在多个实例之间共享此地图以进行缩放。 我已经在使用 consul 来发现对等实例,我目前正在使用 redis 解决这个问题,但是我对我没有利用每台机器的 RAM 的事实不满意(所以从这个意义上说,我觉得 redis 更像是一个数据库而不是一个缓存)。 这就是我喜欢 groupcache 的原因之一。
不过我有一个限制:我的地图一直在变化(我收到了通过 http 更新它的请求)。 因此,对于映射中的键 K1,m[K1] 很可能会非常频繁地更新(可能每 1 秒或更短)。
所以我的问题是:
谢谢!
嘿@orcaman。 我只是另一个 Groupcache 用户,但我希望我能回答你的问题。
首先,要记住的两件最重要的事情是 Groupcache 是只读缓存,这意味着您无法更新其中的键。 其次,该数据被认为是不可变的且不会过期。 它基本上只是一个分布式 LRU。 所以如果你需要经常更新密钥,GC 不是一个好的选择。
但是,您可以通过键操作来模拟现有数据的过期或更改。
就我而言,我需要大约一个小时的密钥过期时间。 我所做的是将下一轮小时的时间戳添加到我想要获取的任何密钥中。 因此,当一个小时过去后,我的应用程序请求更改密钥的这一部分,从 Groupcache 的角度来看,我正在请求一个新密钥。 旧的将通过 LRU 机制被驱逐,因为没有人再接触它。
但是,如果您需要不断地写入密钥,并在第二个分辨率下过期,则最好使用 redis 或 memcache。 我会选择 memcache,因为它更容易扩展更多的服务器。
谢谢@dvirsky !
我想我明白了。
没问题,虽然我有点希望在以色列场景中更多地采用 Groupcache。 你知道还有其他公司在使用它吗? :)
我们可能仍在使用它,只是等待正确的用例。 :-)
我不知道以色列场景中有很多地鼠,所以我不知道 Groupcache 用户。 期待在即将到来的 go 聚会中与您会面(如果您来了,那就是)。
凉爽的。 我们将其用作传出 HTTP 缓存(即我们向第 3 方发出的缓存请求)。 我们可能会在某个时候打开这个实现。
不确定 Go 聚会,希望我能成功。
@dvirsky和@bradfitz - 在我的用例中,我想处理 TTL [计划将当前小时时间戳添加到密钥]。 我有以下问题,
1.LRU机制是如何去除key的。 我们可以设置不使用密钥的最短持续时间[将其标记为过期]吗?
2.如果不是,这取决于为缓存分配的内存。 当数据超过分配的最近最少使用的将被删除? 在这种情况下,我们如何处理内存平衡以不删除当前小时数据?
你能就此提出一些建议吗?
@dvirsky感谢您的出色回答.. 但是,当项目同时被“驱逐”时,您是否每小时看到 CPU 和内存的小高峰?
@qbig这取决于您如何实施到期。 这是我所做的:
// turn a ttl into an expiration timestamp, using discrete time windows.
// i.e. ask for an hour and get the nearest hour end as the expiration point.
//
// We pad these discrete boundaries pseudo random margin (based on hashing the key)
// to avoid hitting the cache too hard if all requests expire at once
//
// This can be seconds from now even if you cache for days :)
func calcExpiration(ttl int64, key string, now int64) int64 {
//we calculate the non discrete expiration, relative to current time
expires := now
var padding int64 = 0
if ttl > 0 {
// now we want to pad it so we'll no expire all reqeusts for a given time window at once
// to be consistent, the seed of the padding is a hash on the url
h := fnv.New32a()
h.Write([]byte(key))
padding = int64(h.Sum32()) % ttl
// not sure this is correct - I wrote it long ago :)
expires += (ttl - (expires % ttl)) - padding
if expires < now {
expires += ttl
}
}
return expires
}
@orcaman看看https://tarantool.org/
最有用的评论
嘿@orcaman。 我只是另一个 Groupcache 用户,但我希望我能回答你的问题。
首先,要记住的两件最重要的事情是 Groupcache 是只读缓存,这意味着您无法更新其中的键。 其次,该数据被认为是不可变的且不会过期。 它基本上只是一个分布式 LRU。 所以如果你需要经常更新密钥,GC 不是一个好的选择。
但是,您可以通过键操作来模拟现有数据的过期或更改。
就我而言,我需要大约一个小时的密钥过期时间。 我所做的是将下一轮小时的时间戳添加到我想要获取的任何密钥中。 因此,当一个小时过去后,我的应用程序请求更改密钥的这一部分,从 Groupcache 的角度来看,我正在请求一个新密钥。 旧的将通过 LRU 机制被驱逐,因为没有人再接触它。
但是,如果您需要不断地写入密钥,并在第二个分辨率下过期,则最好使用 redis 或 memcache。 我会选择 memcache,因为它更容易扩展更多的服务器。