golang支持泛型的带过期时间内存缓存插件库ttlcache的使用
golang支持泛型的带过期时间内存缓存插件库ttlcache的使用
TTLCache - 带项目过期和泛型的内存缓存
TTLCache是一个支持泛型的带过期时间的内存缓存库,具有以下特性:
- 简单API
- 类型参数
- 项目过期和自动删除
- 每次
Get
调用自动延长过期时间 Loader
接口可用于加载/懒初始化缺失的缓存项- 线程安全
- 事件处理器(插入、更新和驱逐)
- 指标
安装
go get github.com/jellydator/ttlcache/v3
使用
基本用法
func main() {
// 创建缓存实例,指定键类型为string,值类型为string
cache := ttlcache.New[string, string]()
// 插入数据
cache.Set("key1", "value1", ttlcache.DefaultTTL) // 使用默认TTL
cache.Set("key2", "value2", ttlcache.NoTTL) // 永不过期
cache.Set("key3", "value3", 10 * time.Minute) // 自定义TTL
// 获取数据
if item := cache.Get("key1"); item != nil {
fmt.Println(item.Value(), item.ExpiresAt())
}
// 检查键是否存在
exists := cache.Has("key2")
// 删除数据
cache.Delete("key3")
cache.DeleteExpired() // 删除所有过期项
cache.DeleteAll() // 删除所有项
}
自动过期删除
func main() {
// 创建带TTL的缓存
cache := ttlcache.New[string, string](
ttlcache.WithTTL[string, string](30 * time.Minute),
)
// 启动自动过期项删除
go cache.Start()
// 或者手动控制过期项删除
for {
time.Sleep(1 * time.Hour)
cache.DeleteExpired()
}
}
事件监听
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.Key(), item.Value())
})
// 更新事件
cache.OnUpdate(func(ctx context.Context, item *ttlcache.Item[string, string]) {
fmt.Println("更新:", item.Key(), item.Value())
})
// 驱逐事件
cache.OnEviction(func(ctx context.Context, reason ttlcache.EvictionReason, item *ttlcache.Item[string, string]) {
fmt.Printf("驱逐: %s (原因: %v)\n", item.Key(), reason)
})
cache.Set("event", "test", ttlcache.DefaultTTL)
cache.DeleteAll()
}
自定义加载器
func main() {
// 创建自定义加载器
loader := ttlcache.LoaderFunc[string, string](
func(c *ttlcache.Cache[string, string], key string) *ttlcache.Item[string, string] {
// 模拟从数据库或其他来源加载数据
value := "loaded-value-for-" + key
return c.Set(key, value, ttlcache.DefaultTTL)
},
)
// 创建带加载器的缓存
cache := ttlcache.New[string, string](
ttlcache.WithLoader[string, string](loader),
)
// 获取不存在的键会自动调用加载器
item := cache.Get("some-key")
fmt.Println(item.Value()) // 输出: loaded-value-for-some-key
}
限制缓存大小
func main() {
// 创建带最大内存限制的缓存
cache := ttlcache.New[string, string](
ttlcache.WithMaxCost[string, string](5120, func(item ttlcache.CostItem[string, string]) uint64 {
// 计算每个项的"成本"(这里简单使用键值长度之和)
return uint64(len(item.Key()) + len(item.Value()))
}),
)
// 添加数据
cache.Set("large", strings.Repeat("a", 1024), ttlcache.DefaultTTL)
}
完整示例
package main
import (
"context"
"fmt"
"time"
"github.com/jellydator/ttlcache/v3"
)
func main() {
// 创建缓存实例
cache := ttlcache.New[string, string](
ttlcache.WithTTL[string, string](30 * time.Minute),
ttlcache.WithCapacity[string, string](100),
)
// 设置事件处理器
cache.OnInsertion(func(ctx context.Context, item *ttlcache.Item[string, string]) {
fmt.Printf("插入项: %s=%s (过期时间: %v)\n",
item.Key(), item.Value(), item.ExpiresAt())
})
cache.OnEviction(func(ctx context.Context, reason ttlcache.EvictionReason, item *ttlcache.Item[string, string]) {
fmt.Printf("驱逐项: %s (原因: %v)\n", item.Key(), reason)
})
// 启动自动清理
go cache.Start()
defer cache.Stop()
// 添加数据
cache.Set("name", "张三", ttlcache.DefaultTTL)
cache.Set("age", "30", 10 * time.Second) // 10秒后过期
// 获取数据
if item := cache.Get("name"); item != nil {
fmt.Println("获取到name:", item.Value())
}
// 等待过期
time.Sleep(11 * time.Second)
if item := cache.Get("age"); item == nil {
fmt.Println("age已过期")
}
// 使用加载器
loader := ttlcache.LoaderFunc[string, string](
func(c *ttlcache.Cache[string, string], key string) *ttlcache.Item[string, string] {
return c.Set(key, "default-value", ttlcache.DefaultTTL)
},
)
cache = ttlcache.New[string, string](
ttlcache.WithLoader[string, string](loader),
)
fmt.Println("自动加载的值:", cache.Get("auto-loaded").Value())
}
这个库非常适合需要内存缓存且支持过期时间的场景,如API响应缓存、会话存储等。通过泛型支持,可以确保类型安全,同时提供了丰富的配置选项和事件机制。
更多关于golang支持泛型的带过期时间内存缓存插件库ttlcache的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang支持泛型的带过期时间内存缓存插件库ttlcache的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Golang 中使用 ttlcache 实现带过期时间的缓存
ttlcache 是一个流行的 Go 语言内存缓存库,支持基于时间的自动过期功能。下面我将详细介绍如何使用它。
安装 ttlcache
首先安装 ttlcache 库:
go get github.com/jellydator/ttlcache/v3
基本使用示例
package main
import (
"fmt"
"time"
"github.com/jellydator/ttlcache/v3"
)
func main() {
// 创建一个带过期时间的缓存
cache := ttlcache.New[string, string](
ttlcache.WithTTL[string, string](5 * time.Minute), // 默认5分钟过期
)
// 设置缓存项,带自定义过期时间
cache.Set("key1", "value1", ttlcache.DefaultTTL)
cache.Set("key2", "value2", 10*time.Minute) // 单独设置10分钟过期
// 获取缓存值
if item := cache.Get("key1"); item != nil {
fmt.Println("key1:", item.Value())
}
// 删除缓存项
cache.Delete("key2")
// 检查是否存在
if !cache.Has("key2") {
fmt.Println("key2 已不存在")
}
}
高级功能
1. 设置全局默认过期时间
cache := ttlcache.New[string, int](
ttlcache.WithTTL[string, int](30 * time.Minute),
)
2. 自动删除过期项
cache := ttlcache.New[string, interface{}](
ttlcache.WithTTL[string, interface{}](1 * time.Hour),
ttlcache.WithDisableTouchOnHit[string, interface{}](), // 访问时不重置过期时间
)
// 启动自动清理协程
go cache.Start()
defer cache.Stop()
3. 设置缓存大小限制
cache := ttlcache.New[string, float64](
ttlcache.WithTTL[string, float64](15 * time.Minute),
ttlcache.WithCapacity[string, float64](1000), // 最多1000个条目
)
4. 事件监听
loader := ttlcache.LoaderFunc[string, string](
func(c *ttlcache.Cache[string, string], key string) *ttlcache.Item[string, string] {
// 当缓存未命中时自动加载
value := "auto-loaded-value-for-" + key
item := c.Set(key, value, ttlcache.DefaultTTL)
return item
},
)
cache := ttlcache.New[string, string](
ttlcache.WithLoader[string, string](loader),
ttlcache.WithTTL[string, string](10 * time.Minute),
)
// 设置事件回调
cache.OnInsertion(func(ctx context.Context, i *ttlcache.Item[string, string]) {
fmt.Println("插入:", i.Key(), i.Value())
})
cache.OnEviction(func(ctx context.Context, r ttlcache.EvictionReason, i *ttlcache.Item[string, string]) {
fmt.Println("淘汰:", i.Key(), "原因:", r)
})
5. 复杂类型缓存示例
type User struct {
ID int
Name string
Email string
}
func main() {
userCache := ttlcache.New[int, *User](
ttlcache.WithTTL[int, *User](1 * time.Hour),
)
// 存储用户对象
userCache.Set(1, &User{ID: 1, Name: "张三", Email: "zhangsan@example.com"}, ttlcache.DefaultTTL)
// 获取用户对象
if item := userCache.Get(1); item != nil {
user := item.Value()
fmt.Printf("用户ID: %d, 姓名: %s\n", user.ID, user.Name)
}
}
注意事项
- ttlcache 是线程安全的,可以在多个 goroutine 中并发使用
- 对于大量缓存项,建议设置合理的 Capacity 限制
- 过期时间是粗略的,不保证精确到毫秒级
- 考虑使用
Start()
和Stop()
来管理后台清理协程的生命周期 - 对于生产环境,建议添加监控来跟踪缓存命中率和内存使用情况
ttlcache 提供了简单而强大的内存缓存功能,特别适合需要自动过期特性的场景。根据你的具体需求,可以选择合适的配置选项来优化缓存行为。