Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

基于 Go 实验特性 Arena 的缓存实现。 #12

Open
flycash opened this issue Aug 28, 2023 · 2 comments
Open

基于 Go 实验特性 Arena 的缓存实现。 #12

flycash opened this issue Aug 28, 2023 · 2 comments

Comments

@flycash
Copy link
Contributor

flycash commented Aug 28, 2023

仅限中文

使用场景

即便是使用 sync.Poll 来缓存对象,依旧会加重 GO 的垃圾回收负担。所以一种想法是在 GO 垃圾回收之外设计一个缓存机制,这也就是说我们可以考虑使用 Arena 来设计一个缓存。

这个设计可以分成两部分,缓存本身的结构就直接用 GO 来定义,本身也归属于 GO 垃圾回收管理。

但是缓存的键值对中的值就被 Arena 管理。

在这种理念下,我们可以认为,缓存本身的开销,以及键值对中的键的开销,是可以容忍的,但是值的开销是不能容忍,所以需要放到堆外。

行业分析

在 ekit 里面有一个 Arena Pool,作为一个使用 Arena 的对象池,可以考虑借鉴。

可行方案

// memory/arena/cache.go
// 文件头加上这个编译标签
//go:build goexperiment.arenas
type Cache struct {
	vals map[string]*arena.Arena // 也可能映射过去了一个结构体,然后结构体有一个 Arena 字段,还有一些过期时间等的设置。
}

最基本的定义,当然为了维系缓存自身,你还是需要引入其它字段。

当缓存过期,或者被删除的时候,需要调用 arena 上的 Free 方法释放内存。

@junwense
Copy link

我看了ekit.arena的设计,是要把obj进行包装,然后在cache的get set update remove方法进行处理arena么。

@flycash
Copy link
Contributor Author

flycash commented Aug 29, 2023

大概是这么个思路。

但是缓存用起来有另外一个问题,比如说我取走了 A,但是我一直在用。这个时候缓存里面的 A 过期了,这时候你并不能删除 A(调用 Arena 的 Free),而是要等我用完了 A。目前的难点就是,你不知道我究竟有没有在用 A。

这里,你可以认为,用户在 Get 的时候,是真的把数据都取走了。也就是 GET 接近一种 DelAndGet 的语义。后面我们再来考虑怎么解决这个问题。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: 🔖 Ready
Development

No branches or pull requests

2 participants