地图与TTL选项在Go



我需要建立一个这样的数据结构:

map[string]SomeType 

但是它必须存储值大约10分钟,然后从内存中清除。第二个条件是记录的数量——必须是巨大的。这个数据结构必须至少每秒增加2-5K条记录

那么,在Go中最正确的方法是什么呢?

我正在尝试为每个新元素创建超时例程。以及一个(或多个)垃圾收集器例程,该例程具有接收超时和清除元素的通道。但我不确定这是最清晰的方式。有数百万个带有超时的等待程序可以吗?

谢谢。

您必须创建一个结构体来保存您的map,并提供自定义的get/put/delete函数来访问它。

请注意,每秒2-5k的访问实际上并没有那么多,所以您不必担心。

下面是一个简单的实现:

type item struct {
    value      string
    lastAccess int64
}
type TTLMap struct {
    m map[string]*item
    l sync.Mutex
}
func New(ln int, maxTTL int) (m *TTLMap) {
    m = &TTLMap{m: make(map[string]*item, ln)}
    go func() {
        for now := range time.Tick(time.Second) {
            m.l.Lock()
            for k, v := range m.m {
                if now.Unix() - v.lastAccess > int64(maxTTL) {
                    delete(m.m, k)
                }
            }
            m.l.Unlock()
        }
    }()
    return
}
func (m *TTLMap) Len() int {
    return len(m.m)
}
func (m *TTLMap) Put(k, v string) {
    m.l.Lock()
    it, ok := m.m[k]
    if !ok {
        it = &item{value: v}
        m.m[k] = it
    }
    it.lastAccess = time.Now().Unix()
    m.l.Unlock()
}
func (m *TTLMap) Get(k string) (v string) {
    m.l.Lock()
    if it, ok := m.m[k]; ok {
        v = it.value
        it.lastAccess = time.Now().Unix()
    }
    m.l.Unlock()
    return
}
游乐场

注释(2020-09-23):由于某种原因,当前版本的操场上的时间分辨率是很远的,这工作得很好,但是要在操场上尝试,你必须将睡眠更改为3-5秒。

看看buntdb。

tinykv不再被维护

只是为了记录,我有同样的问题,并编写了一个内部使用map的tinykv包。

  • 使用time.Time堆来处理超时,所以它不会覆盖整个地图。
  • 创建实例时可以设置最大时间间隔。但是检查超时的实际间隔可以是time.Duration大于0小于max的任何值,基于最后一个超时的项。
  • 提供CASTake功能
  • 可以设置一个回调(可选),通知哪个键和值超时。
  • 超时可以是显式的,也可以是滑动的。

我建议使用Map的golang的内置包sync,它很容易使用,已经处理并发https://golang.org/pkg/sync/#Map

相关内容

  • 没有找到相关文章