竹简文档
缓存

概述

xCache 基于 Manager 的泛型缓存系统,支持 Redis / Memory 双后端

缓存

xCache 是泛型缓存系统,通过 Manager 统一门面支持 RedisMemory 两种后端,提供类型安全的 KeyCache / HashCache / SetCache / ListCache 四种接口。切换后端只需更换一个 option,无需修改业务代码。

import xCache "github.com/bamboo-services/bamboo-base-go/major/cache"

双后端架构

字段

类型

核心结构 — Manager

Manager 是业务访问缓存的唯一入口。它持有底层后端实例,通过 KeyCacheOf / HashCacheOf / SetCacheOf / ListCacheOf 四个泛型工厂方法返回对应后端的接口实现。

type Manager struct {
    // 私有字段,通过 getter 访问
}

// Getter 方法
func (m *Manager) Type() CacheType                // 当前后端类型
func (m *Manager) Redis() *redis.Client           // Redis 客户端(仅 Redis 后端非 nil)
func (m *Manager) Memory() *xCacheMemory.Store    // Memory 存储(仅 Memory 后端非 nil)
func (m *Manager) TTL() time.Duration             // 默认过期时间
func (m *Manager) Codec() Codec                   // 当前序列化器
func (m *Manager) Logo(*xLog.LogNamedLogger)      // 日志器

ManagerOption 选项

创建 Manager 时传入函数式选项,控制后端实例、TTL 和序列化器:

字段

类型

初始化

Redis 后端

import (
    "time"

    xCache "github.com/bamboo-services/bamboo-base-go/major/cache"
    "github.com/redis/go-redis/v9"
)

rdb := redis.NewClient(&redis.Options{
    Addr: "localhost:6379",
    DB:   0,
})

// 初始化缓存管理器 — 使用 Redis 后端
manager := xCache.NewManager(xCache.CacheTypeRedis,
    xCache.WithRedisClient(rdb),
    xCache.WithManagerTTL(24*time.Hour),
)

// 从 Manager 获取 KeyCache 实现
kc := xCache.KeyCacheOf[string, User](manager)

Memory 后端

import (
    xCache "github.com/bamboo-services/bamboo-base-go/major/cache"
    xCacheMemory "github.com/bamboo-services/bamboo-base-go/major/cache/memory"
)

// 创建内存存储,参数为清理间隔
store := xCacheMemory.NewStore(5 * time.Minute)

// 初始化缓存管理器 — 使用 Memory 后端
manager := xCache.NewManager(xCache.CacheTypeMemory,
    xCache.WithMemoryStore(store),
    xCache.WithManagerTTL(10*time.Minute),
)

kc := xCache.KeyCacheOf[string, User](manager)

生产环境建议通过 Option 声明式配置 自动装配 Manager。详见 声明式配置

工厂方法

由于 Go 不允许接口/方法带类型参数,KeyCacheOf / HashCacheOf / SetCacheOf / ListCacheOf 作为包级泛型函数,根据 Manager.Type() 分发给对应后端实现。

字段

类型

缓存接口类型(Driver 层)

xCache 通过 type aliasdriver 包的接口类型重新导出,保持向后兼容:

type (
    KeyCache[K, V] = xCacheDriver.KeyCache[K, V]
    HashCache[K, F, V, S] = xCacheDriver.HashCache[K, F, V, S]
    SetCache[K, V] = xCacheDriver.SetCache[K, V]
    ListCache[K, V] = xCacheDriver.ListCache[K, V]
    Codec = xCacheDriver.Codec
    JSONCodec = xCacheDriver.JSONCodec
    KeyEncoder = xCacheDriver.KeyEncoder
)

写操作选项(SetOption)

v1.1.0 新增。所有写操作(KeyCache.Set / HashCache.Set / HashCache.SetAll / HashCache.SetAllStruct / SetCache.Add / ListCache.Prepend / ListCache.Append)尾部新增 opts ...SetOption 变参,可在单次调用中覆盖默认 TTL 或附加写入条件,不传则沿用 Manager 实例的默认行为。

SetOptionxCache.WithTTL / WithNX / WithXX / WithKeepTTL / WithNoSlide 构造,经 xCacheDriver.ApplySet 合成最终 SetConfig。各选项语义如下:

字段

类型

示例:分布式锁 + TTL 覆盖
import xCache "github.com/bamboo-services/bamboo-base-go/major/cache"

kc := xCache.KeyCacheOf[string, string](manager)

// NX + 短 TTL:实现简易分布式锁(仅当 lock 不存在时写入)
_ = kc.Set(ctx, "lock:order:1", &token, xCache.WithNX(), xCache.WithTTL(30*time.Second))

// KeepTTL:刷新值但保留原过期时间(避免锁被无意延长)
_ = kc.Set(ctx, "lock:order:1", &newToken, xCache.WithKeepTTL())

签名变更提示SetCache.AddListCache.Prepend / ListCache.Append 的入参由变参 ...V 调整为切片 []V,以便在尾部保留 opts ...SetOption 变参位置。升级时需将 sc.Add(ctx, key, "a", "b") 改写为 sc.Add(ctx, key, []string{"a", "b"})

使用场景

KeyCache — 键值对缓存

适用于存储单一对象:用户信息、配置项、Token 缓存。

kc := xCache.KeyCacheOf[string, User](manager)

// 写入(v1.1.0 起尾部可附 SetOption)
_ = kc.Set(ctx, "user:123", &User{Name: "筱锋"}, xCache.WithTTL(5*time.Minute))

// 读取
user, ok, err := kc.Get(ctx, "user:123")

HashCache — 哈希缓存

适用于对象属性存储:用户配置、商品详情、会话数据。

hc := xCache.HashCacheOf[string, string, int, UserConfig](manager)

// 设置字段(v1.1.0 起尾部可附 SetOption)
_ = hc.Set(ctx, "config:123", "theme", 1)
_ = hc.Set(ctx, "config:123", "lang", 2, xCache.WithNoSlide()) // 追加但不滑动 TTL

// 获取字段
theme, ok, err := hc.Get(ctx, "config:123", "theme")

SetCache — 集合缓存

适用于去重数据:用户标签、权限列表、在线用户集合。

sc := xCache.SetCacheOf[string, string](manager)

// 添加成员(v1.1.0 起入参为 []V 切片,尾部可附 SetOption)
_ = sc.Add(ctx, "tags:123", []string{"gopher", "opensource"})

// 检查成员
isMember, err := sc.IsMember(ctx, "tags:123", "gopher")

ListCache — 列表缓存

适用于有序数据:消息队列、操作历史、排行榜。

lc := xCache.ListCacheOf[string, string](manager)

// 左侧推入(v1.1.0 起入参为 []V 切片,尾部可附 SetOption)
_ = lc.Prepend(ctx, "queue:task", []string{"task-1", "task-2"})

// 右侧弹出
val, err := lc.Pop(ctx, "queue:task")

自定义序列化器

默认使用 JSONCodec。可通过 WithCodec 替换为自定义实现:

// 实现 xCache.Codec 接口
type GobCodec struct{}

func (g GobCodec) Marshal(v any) ([]byte, error) { /* ... */ }
func (g GobCodec) Unmarshal(data []byte, v any) error { /* ... */ }

manager := xCache.NewManager(xCache.CacheTypeRedis,
    xCache.WithRedisClient(rdb),
    xCache.WithCodec(GobCodec{}),
)

资源释放

// 应用退出时释放资源(Memory 后端会停止 janitor goroutine)
defer manager.Close()

// 可安全多次调用(内部 sync.Once 保护)
manager.Close()

设计特点

后端透明

业务代码无感后端差异。KeyCacheOf / SetCacheOf 等接口在 Redis 和 Memory 下行为一致,切换只需改一行初始化参数。

泛型类型安全

所有接口支持 Go 泛型,编译期保证键值类型正确:

kc := xCache.KeyCacheOf[string, User](manager)
// kc.Set(ctx, 123, ...) // 编译错误:键类型必须是 string

统一日志

通过 WithLogger 注入 xLog 命名日志器,缓存操作自动记录调试与错误信息。

下一步

On this page