jellydator/ttlcache
GitHub: jellydator/ttlcache
一个带有泛型支持和过期自动清理机制的 Go 内存缓存库,帮助开发者高效管理进程内临时数据。
Stars: 1267 | Forks: 142
## TTLCache - 带有过期时间和泛型的内存缓存
[](https://pkg.go.dev/github.com/jellydator/ttlcache/v3)
[](https://github.com/jellydator/ttlcache/actions/workflows/go.yml)
[](https://coveralls.io/github/jellydator/ttlcache?branch=master)
[](https://goreportcard.com/report/github.com/jellydator/ttlcache/v3)
## 功能
- 简单的 API
- 类型参数
- 条目过期和自动删除
- 每次调用 `Get` 时自动延长过期时间
- `Loader` 接口可用于加载/懒加载缺失的缓存条目
- 线程安全
- 事件处理程序(插入、更新和淘汰)
- 指标
## 安装
```
go get github.com/jellydator/ttlcache/v3
```
## 用法
`ttlcache` 的主要类型是 `Cache`。它代表一个单一的
内存数据存储。
要创建一个新的 `ttlcache.Cache` 实例,应该调用
`ttlcache.New()` 函数:
```
func main() {
cache := ttlcache.New[string, string]()
}
```
请注意,默认情况下,新的缓存实例不允许其
任何条目过期或被自动删除。但是,可以
通过向 `ttlcache.New()` 函数传递一些额外的选项
并调用 `cache.Start()` 方法来激活此功能:
```
func main() {
cache := ttlcache.New[string, string](
ttlcache.WithTTL[string, string](30 * time.Minute),
)
go cache.Start() // starts automatic expired item deletion
}
```
尽管 `cache.Start()` 方法能很好地处理过期条目的删除,
但有时使用 `ttlcache` 的系统可能需要
自行决定何时删除过期条目。例如,它可能
只需要在资源负载最低时(例如,午夜之后,
当用户数/HTTP 请求数下降时)删除它们。因此,在
这种情况下,系统可以不调用 `cache.Start()`,而是
定期调用 `cache.DeleteExpired()`:
```
func main() {
cache := ttlcache.New[string, string](
ttlcache.WithTTL[string, string](30 * time.Minute),
)
for {
time.Sleep(4 * time.Hour)
cache.DeleteExpired()
}
}
```
`ttlcache.Cache` 中存储的数据可以通过
`Set`、`Get`、`Delete`、`Has` 等方法进行检索、检查和更新:
```
func main() {
cache := ttlcache.New[string, string](
ttlcache.WithTTL[string, string](30 * time.Minute),
)
// insert data
cache.Set("first", "value1", ttlcache.DefaultTTL)
cache.Set("second", "value2", ttlcache.NoTTL)
cache.Set("third", "value3", ttlcache.DefaultTTL)
// retrieve data
item := cache.Get("first")
fmt.Println(item.Value(), item.ExpiresAt())
// check key
ok := cache.Has("third")
// delete data
cache.Delete("second")
cache.DeleteExpired()
cache.DeleteAll()
// retrieve data if in cache otherwise insert data
item, retrieved := cache.GetOrSet("fourth", "value4", WithTTL[string, string](ttlcache.DefaultTTL))
// retrieve and delete data
item, present := cache.GetAndDelete("fourth")
}
```
要订阅插入、更新和淘汰事件,应使用 `cache.OnInsertion()`、`cache.OnUpdate()` 和
`cache.OnEviction()` 方法:
```
func main() {
cache := ttlcache.New[string, string](
ttlcache.WithTTL[string, string](30 * time.Minute),
ttlcache.WithCapacity[string, string](300),
)
cache.OnInsertion(func(ctx context.Context, item *ttlcache.Item[string, string]) {
fmt.Println(item.Value(), item.ExpiresAt())
})
cache.OnUpdate(func(ctx context.Context, item *ttlcache.Item[string, string]) {
fmt.Println(item.Value(), item.ExpiresAt())
})
cache.OnEviction(func(ctx context.Context, reason ttlcache.EvictionReason, item *ttlcache.Item[string, string]) {
if reason == ttlcache.EvictionReasonCapacityReached {
fmt.Println(item.Key(), item.Value())
}
})
cache.Set("first", "value1", ttlcache.DefaultTTL)
cache.DeleteAll()
}
```
要在缓存中不包含数据时加载数据,可以使用自定义的
或现有的 `ttlcache.Loader` 实现:
```
func main() {
loader := ttlcache.LoaderFunc[string, string](
func(c *ttlcache.Cache[string, string], key string) *ttlcache.Item[string, string] {
// load from file/make an HTTP request
item := c.Set("key from file", "value from file")
return item
},
)
cache := ttlcache.New[string, string](
ttlcache.WithLoader[string, string](loader),
)
item := cache.Get("key from file")
}
```
要根据超出其可容纳条目数量的标准来限制缓存的容量,`ttlcache.WithMaxCost` 选项允许
实现自定义策略。以下示例展示了如何
将缓存条目的内存使用量限制为约 5KiB。
```
import (
"github.com/jellydator/ttlcache"
)
func main() {
cache := ttlcache.New[string, string](
ttlcache.WithMaxCost[string, string](5120, func(item ttlcache.CostItem[string, string]) uint64 {
// Note: The below line doesn't include memory used by internal
// structures or string metadata for the key and the value.
return uint64(len(item.Key) + len(item.Value))
}),
)
cache.Set("first", "value1", ttlcache.DefaultTTL)
}
```
## 示例
请参阅 [示例](https://github.com/jellydator/ttlcache/tree/v3/examples)
目录,其中包含演示如何使用 `ttlcache` 的应用程序。
标签:EVTX分析, Go, Ruby工具, 内存数据库, 开发组件, 日志审计, 泛型, 缓存