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 等多种存储后端。下面我将详细介绍其使用方法和示例代码。

主要特性

  1. 支持多级缓存链式组合
  2. 内置内存、Redis、Memcached 等存储后端
  3. 简单的 API 设计
  4. 支持缓存过期时间设置
  5. 支持缓存穿透保护

安装

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项目中缓存管理的优秀选择。

在实际项目中,可以根据业务需求选择合适的缓存组合,并合理设置各级缓存的过期时间,以达到最佳的性能和一致性平衡。

回到顶部