golang多存储缓存库gocache支持内存、Redis、Memcache等链式缓存
Golang多存储缓存库gocache支持内存、Redis、Memcache等链式缓存
概述
Gocache是一个Go语言的缓存库,提供了多种缓存功能和存储支持。主要特性包括:
- ✅ 多种缓存存储:支持内存、Redis、Memcache等
- ✅ 链式缓存:可以设置多个缓存的优先级顺序(例如先内存后Redis)
- ✅ 可加载缓存:支持回调函数自动填充缓存
- ✅ 指标缓存:记录缓存使用情况的统计信息
- ✅ 自动序列化:自动将缓存值序列化为结构体
- ✅ 默认值和覆盖:可以设置默认值并在设置数据时覆盖
- ✅ 缓存失效:支持过期时间和标签失效
- ✅ 泛型支持
内置存储支持
- 内存存储(基于bigcache)
- 内存存储(基于ristretto)
- 内存存储(基于go-cache)
- Memcache
- Redis
- Redis(基于rueidis)
- Freecache
- Pegasus
- Hazelcast
安装
首先安装核心库:
go get github.com/eko/gocache/lib/v4
然后根据需要安装对应的存储驱动:
go get github.com/eko/gocache/store/bigcache/v4
go get github.com/eko/gocache/store/freecache/v4
go get github.com/eko/gocache/store/go_cache/v4
go get github.com/eko/gocache/store/hazelcast/v4
go get github.com/eko/gocache/store/memcache/v4
go get github.com/eko/gocache/store/pegasus/v4
go get github.com/eko/gocache/store/redis/v4
go get github.com/eko/gocache/store/rediscluster/v4
go get github.com/eko/gocache/store/rueidis/v4
go get github.com/eko/gocache/store/ristretto/v4
使用示例
简单Redis缓存示例
import (
"github.com/eko/gocache/lib/v4/cache"
"github.com/eko/gocache/store/redis/v4"
)
// 初始化Redis存储
redisStore := redis_store.NewRedis(redis.NewClient(&redis.Options{
Addr: "127.0.0.1:6379",
}))
// 创建缓存管理器
cacheManager := cache.New[string](redisStore)
// 设置缓存值,15秒过期
err := cacheManager.Set(ctx, "my-key", "my-value", store.WithExpiration(15*time.Second))
if err != nil {
panic(err)
}
// 获取缓存值
value, err := cacheManager.Get(ctx, "my-key")
if err != nil {
panic(err)
}
// 删除缓存
cacheManager.Delete(ctx, "my-key")
// 清空所有缓存
cacheManager.Clear(ctx)
链式缓存示例(内存+Redis)
// 初始化Ristretto内存缓存
ristrettoCache, err := ristretto.NewCache(&ristretto.Config{
NumCounters: 1000,
MaxCost: 100,
BufferItems: 64,
})
if err != nil {
panic(err)
}
// 初始化Redis客户端
redisClient := redis.NewClient(&redis.Options{Addr: "127.0.0.1:6379"})
// 初始化存储
ristrettoStore := ristretto_store.NewRistretto(ristrettoCache)
redisStore := redis_store.NewRedis(redisClient, store.WithExpiration(5*time.Second))
// 创建链式缓存(先内存后Redis)
cacheManager := cache.NewChain[any](
cache.New[any](ristrettoStore),
cache.New[any](redisStore),
)
// 使用缓存...
可加载缓存示例
type Book struct {
ID string
Name string
}
// 初始化Redis存储
redisStore := redis_store.NewRedis(redis.NewClient(&redis.Options{Addr: "127.0.0.1:6379"}))
// 定义加载函数
loadFunction := func(ctx context.Context, key any) (*Book, error) {
// 从数据源获取数据
return &Book{ID: "1", Name: "My test amazing book"}, nil
}
// 创建可加载缓存
cacheManager := cache.NewLoadable[*Book](
loadFunction,
cache.New[*Book](redisStore),
)
// 获取数据,如果缓存不存在会自动调用loadFunction
book, err := cacheManager.Get(ctx, "book-1")
带指标的缓存示例
// 初始化Redis存储
redisStore := redis_store.NewRedis(redis.NewClient(&redis.Options{Addr: "127.0.0.1:6379"}))
// 初始化Prometheus指标服务
promMetrics := metrics.NewPrometheus("my-test-app")
// 创建带指标的缓存
cacheManager := cache.NewMetric[any](
promMetrics,
cache.New[any](redisStore),
)
// 使用缓存...
自动序列化示例
// 初始化Redis存储
redisStore := redis_store.NewRedis(redis.NewClient(&redis.Options{Addr: "127.0.0.1:6379"}))
// 创建缓存管理器
cacheManager := cache.New[any](redisStore)
// 创建序列化器
marshal := marshaler.New(cacheManager)
// 定义结构体
key := BookQuery{Slug: "my-test-amazing-book"}
value := Book{ID: "1", Name: "My test amazing book", Slug: "my-test-amazing-book"}
// 设置缓存(自动序列化)
err := marshal.Set(ctx, key, value)
if err != nil {
panic(err)
}
// 获取缓存(自动反序列化)
var result Book
returnedValue, err := marshal.Get(ctx, key, &result)
if err != nil {
panic(err)
}
基于标签的缓存失效
// 设置缓存并附加标签
err := marshal.Set(ctx, key, value, store.WithTags([]string{"book"}))
if err != nil {
panic(err)
}
// 使所有带有"book"标签的缓存失效
err := marshal.Invalidate(ctx, store.WithInvalidateTags([]string{"book"}))
if err != nil {
panic(err)
}
完整示例
package main
import (
"fmt"
"log"
"time"
"github.com/eko/gocache/lib/v4/cache"
"github.com/eko/gocache/lib/v4/store"
"github.com/redis/go-redis/v9"
)
func main() {
// 初始化Redis存储
redisStore := redis_store.NewRedis(redis.NewClient(&redis.Options{
Addr: "127.0.0.1:6379",
}), nil)
// 创建缓存管理器
cacheManager := cache.New[string](redisStore)
// 设置缓存值,15秒过期
err := cacheManager.Set(ctx, "my-key", "my-value", store.WithExpiration(15*time.Second))
if err != nil {
panic(err)
}
// 获取缓存值
key := "my-key"
value, err := cacheManager.Get(ctx, key)
if err != nil {
log.Fatalf("无法从缓存获取键'%s': %v", key, err)
}
fmt.Printf("%#+v\n", value)
}
Gocache提供了灵活的缓存解决方案,可以根据项目需求组合不同的缓存策略和存储后端。
更多关于golang多存储缓存库gocache支持内存、Redis、Memcache等链式缓存的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang多存储缓存库gocache支持内存、Redis、Memcache等链式缓存的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
GoCache - Golang多存储缓存库
GoCache 是一个支持多级缓存的 Golang 库,可以链式组合内存、Redis、Memcached 等多种存储后端。下面我将详细介绍其使用方法和示例代码。
主要特性
- 支持多级缓存链式组合
- 内置内存、Redis、Memcached 等存储后端
- 简单的 API 设计
- 支持缓存过期时间设置
- 支持缓存穿透保护
安装
go get github.com/eko/gocache/v2
基本使用示例
1. 仅使用内存缓存
package main
import (
"fmt"
"time"
"github.com/eko/gocache/v2/cache"
"github.com/eko/gocache/v2/store"
)
func main() {
// 初始化内存存储
memoryStore := store.NewMemoryStore()
// 创建缓存管理器
cacheManager := cache.New(memoryStore)
// 设置缓存
err := cacheManager.Set("my-key", []byte("my-value"), &store.Options{
Expiration: 5 * time.Minute,
})
if err != nil {
panic(err)
}
// 获取缓存
value, err := cacheManager.Get("my-key")
if err != nil {
panic(err)
}
fmt.Println(string(value)) // 输出: my-value
// 删除缓存
err = cacheManager.Delete("my-key")
if err != nil {
panic(err)
}
}
2. 链式缓存(内存 + Redis)
package main
import (
"fmt"
"time"
"github.com/eko/gocache/v2/cache"
"github.com/eko/gocache/v2/store"
redisStore "github.com/eko/gocache/store/redis/v2"
"github.com/go-redis/redis/v8"
)
func main() {
// 初始化Redis客户端
redisClient := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
})
// 初始化存储
memoryStore := store.NewMemoryStore()
redisStore := redisStore.NewRedis(redisClient)
// 创建链式缓存 - 先查内存,再查Redis
chainStore := store.NewChain(
store.NewSet(memoryStore, store.WithExpiration(10*time.Minute)),
store.NewSet(redisStore, store.WithExpiration(30*time.Minute)),
)
cacheManager := cache.New(chainStore)
// 设置缓存
err := cacheManager.Set("user-123", []byte("user data"), nil)
if err != nil {
panic(err)
}
// 获取缓存
value, err := cacheManager.Get("user-123")
if err != nil {
panic(err)
}
fmt.Println(string(value)) // 输出: user data
}
3. 使用 Memcached
package main
import (
"fmt"
"time"
"github.com/eko/gocache/v2/cache"
"github.com/eko/gocache/v2/store"
memcacheStore "github.com/eko/gocache/store/memcache/v2"
"github.com/bradfitz/gomemcache/memcache"
)
func main() {
// 初始化Memcached客户端
memcacheClient := memcache.New("localhost:11211")
// 初始化Memcached存储
memcacheStore := memcacheStore.NewMemcache(memcacheClient)
cacheManager := cache.New(memcacheStore)
// 设置缓存
err := cacheManager.Set("product-456", []byte("product details"), &store.Options{
Expiration: 1 * time.Hour,
})
if err != nil {
panic(err)
}
// 获取缓存
value, err := cacheManager.Get("product-456")
if err != nil {
panic(err)
}
fmt.Println(string(value)) // 输出: product details
}
4. 复杂链式缓存(内存 + Redis + Memcached)
package main
import (
"fmt"
"time"
"github.com/eko/gocache/v2/cache"
"github.com/eko/gocache/v2/store"
redisStore "github.com/eko/gocache/store/redis/v2"
memcacheStore "github.com/eko/gocache/store/memcache/v2"
"github.com/go-redis/redis/v8"
"github.com/bradfitz/gomemcache/memcache"
)
func main() {
// 初始化各种客户端
redisClient := redis.NewClient(&redis.Options{Addr: "localhost:6379"})
memcacheClient := memcache.New("localhost:11211")
// 初始化各种存储
memoryStore := store.NewMemoryStore()
redisStore := redisStore.NewRedis(redisClient)
memcacheStore := memcacheStore.NewMemcache(memcacheClient)
// 创建链式缓存 - 内存 -> Redis -> Memcached
chainStore := store.NewChain(
store.NewSet(memoryStore, store.WithExpiration(5*time.Minute)),
store.NewSet(redisStore, store.WithExpiration(30*time.Minute)),
store.NewSet(memcacheStore, store.WithExpiration(2*time.Hour)),
)
cacheManager := cache.New(chainStore)
// 设置缓存
err := cacheManager.Set("order-789", []byte("order information"), nil)
if err != nil {
panic(err)
}
// 获取缓存
value, err := cacheManager.Get("order-789")
if err != nil {
panic(err)
}
fmt.Println(string(value)) // 输出: order information
// 清除所有缓存
err = cacheManager.Clear()
if err != nil {
panic(err)
}
}
高级功能
1. 缓存穿透保护
// 在初始化存储时添加选项
memoryStore := store.NewMemoryStore(
store.WithCost(8), // 设置内存成本
store.WithMetrics(), // 启用指标
store.WithPenetrationAware(), // 启用缓存穿透保护
)
2. 自定义序列化
type User struct {
ID int
Name string
}
// 自定义序列化
serialized, err := json.Marshal(User{ID: 1, Name: "John"})
if err != nil {
panic(err)
}
err = cacheManager.Set("user-1", serialized, nil)
if err != nil {
panic(err)
}
// 反序列化
value, err := cacheManager.Get("user-1")
if err != nil {
panic(err)
}
var user User
err = json.Unmarshal(value, &user)
if err != nil {
panic(err)
}
总结
GoCache 提供了灵活的多级缓存解决方案,可以轻松组合不同的存储后端。通过链式缓存,可以实现高效的缓存策略,例如先查内存、再查Redis、最后查数据库等。其简单的API设计和丰富的功能使其成为Golang项目中缓存管理的优秀选择。
在实际项目中,可以根据业务需求选择合适的缓存组合,并合理设置各级缓存的过期时间,以达到最佳的性能和一致性平衡。