Go 中带有 TTL 选项的映射

2024-04-26

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

map[string]SomeType 

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

那么,Go 中最正确的实现方法是什么?

我正在尝试为每个新元素设置超时的 goroutine。以及一个(或多个)垃圾收集器 Goroutine,具有接收超时和清除元素的通道。 但我不确定这是最明确的方法。数以百万计的超时等待 goroutine 可以吗?

Thanks.


您必须创建一个结构来保存您的地图并提供自定义获取/放置/删除函数来访问它。

请注意,每秒 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

}

playground http://play.golang.org/p/gJpkIGocNz

注意(2020-09-23):由于某种原因,当前版本的 Playground 的时间分辨率相差很大,这工作正常,但是要在 Playground 上尝试,您必须将睡眠时间更改为 3-5 秒。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Go 中带有 TTL 选项的映射 的相关文章