cache

package
v0.5.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 29, 2026 License: MIT Imports: 12 Imported by: 0

README

cache - 缓存组件

Go Reference

cache 是 Genesis 的 L2 业务层组件,提供三类缓存入口:

  • Distributed:分布式缓存,当前基于 Redis,支持 KV + Hash + Sorted Set + Batch
  • Local:本地缓存,当前基于进程内存,只提供稳定的 KV 语义。
  • Multi:多级缓存,组合 LocalDistributed,提供两级 KV 策略。

接口设计与取舍详见 genesis-cache-blog.md,完整 API 文档见 go doc ./cache

快速开始

分布式缓存
redisConn, err := connector.NewRedis(&cfg.Redis, connector.WithLogger(logger))
if err != nil {
    return err
}
defer redisConn.Close()

dist, err := cache.NewDistributed(&cache.DistributedConfig{
    Driver:     cache.DriverRedis,
    KeyPrefix:  "myapp:",
    Serializer: "json",
}, cache.WithRedisConnector(redisConn), cache.WithLogger(logger))
if err != nil {
    return err
}

if err := dist.Set(ctx, "user:1001", user, time.Hour); err != nil {
    return err
}

var cachedUser User
if err := dist.Get(ctx, "user:1001", &cachedUser); err != nil {
    return err
}
本地缓存
local, err := cache.NewLocal(&cache.LocalConfig{
    Driver:     cache.DriverOtter,
    MaxEntries: 10000,
    Serializer: "json",
}, cache.WithLogger(logger))
if err != nil {
    return err
}
defer local.Close()

if err := local.Set(ctx, "profile:1001", profile, time.Minute); err != nil {
    return err
}
多级缓存
multi, err := cache.NewMulti(local, dist, &cache.MultiConfig{
    BackfillTTL: time.Minute,
})
if err != nil {
    return err
}

if err := multi.Set(ctx, "user:1001", user, 10*time.Minute); err != nil {
    return err
}

TTL 与错误语义

  • Set(..., ttl > 0) / Expire(..., ttl > 0):使用显式 TTL。
  • Set(..., ttl <= 0) / Expire(..., ttl <= 0):使用组件配置中的 DefaultTTL
  • GetHGetZScore 等未命中时返回 ErrMiss
  • Has 不返回 ErrMiss,而是通过布尔值表达存在性。
  • Expire 返回 (bool, error),其中 bool=false 表示 key 不存在。

配置

DistributedConfig
字段 类型 默认值 说明
Driver DistributedDriverType "redis" 后端驱动类型,当前仅支持 "redis"
KeyPrefix string "" 全局 key 前缀,用于多租户或命名空间隔离
Serializer string "json" 序列化器,支持 "json""msgpack"
DefaultTTL time.Duration 24h ttl<=0 时的兜底 TTL
LocalConfig
字段 类型 默认值 说明
Driver LocalDriverType "otter" 后端驱动类型,当前仅支持 "otter"
MaxEntries int 10000 缓存最大条目数,超出后 LRU 淘汰
Serializer string "json" 序列化器,支持 "json""msgpack"
DefaultTTL time.Duration 1h ttl<=0 时的兜底 TTL
MultiConfig
字段 类型 默认值 说明
LocalTTL time.Duration 0 写入本地缓存时的 TTL,0 表示跟随写入 TTL
BackfillTTL time.Duration 1min 从远端回填本地缓存时使用的 TTL
FailOpenOnLocalError *bool true 本地缓存异常时是否继续访问远端;nil 视为 true

推荐实践

  • Distributed 作为共享缓存和结构化缓存入口。
  • Local 作为进程内热点数据和短路径优化层,使用完毕需调用 Close()
  • Multi 视为两级缓存策略,而不是新的存储引擎。
  • 优先使用明确 TTL,避免把 DefaultTTL 当成长期数据保留策略。
  • 需要 Pipeline、Lua 或高级 Redis 命令时,再使用 RawClient()

测试

go test ./cache/... -count=1
go test -race ./cache/... -count=1

集成测试通过 testcontainers 自动启动 Redis 容器,直接运行即可,无需手动配置 Docker 环境。

相关文档

Documentation

Overview

Package cache 提供 Genesis L2 业务层的缓存组件族,支持分布式缓存、本地缓存和多级缓存。

组件分类:

  • Distributed: 基于 Redis 的分布式缓存,支持 KV / Hash / Sorted Set / Batch。
  • Local: 基于进程内存的本地缓存,提供稳定的 KV 语义。
  • Multi: 组合 Local + Distributed 的两级缓存。

语义约定:

  • Get 等读取操作未命中时返回 ErrMiss。
  • Has 不返回 ErrMiss,而是通过 bool 表达存在性。
  • Set 和 Expire 在 ttl<=0 时使用组件配置中的 DefaultTTL。
  • Local 与 Multi 仅提供 KV 能力;Hash、Sorted Set、Batch 仅由 Distributed 提供。
  • RawClient 用于 Pipeline、Lua 脚本等高级场景,不保证跨后端兼容。

示例:

ctx := context.Background()
dist, _ := cache.NewDistributed(&cache.DistributedConfig{
	Driver:    cache.DriverRedis,
	KeyPrefix: "myapp:",
})
defer dist.Close()

if err := dist.Set(ctx, "user:1001", map[string]any{"name": "alice"}, time.Hour); err != nil {
	return err
}

Index

Constants

View Source
const (
	// DriverRedis 表示 Redis 分布式缓存。
	DriverRedis DistributedDriverType = "redis"

	// DriverOtter 表示基于 otter 的本地缓存。
	DriverOtter LocalDriverType = "otter"
)

Variables

View Source
var (
	// ErrMiss 表示缓存未命中。
	ErrMiss = xerrors.New("cache: miss")

	// ErrNotSupported 表示当前缓存实现不支持该操作。
	ErrNotSupported = xerrors.New("cache: operation not supported")

	// ErrRedisConnectorRequired 表示分布式缓存缺少 Redis 连接器。
	ErrRedisConnectorRequired = xerrors.New("cache: redis connector is required")

	// ErrLocalCacheRequired 表示多级缓存缺少本地缓存实例。
	ErrLocalCacheRequired = xerrors.New("cache: local cache is required")

	// ErrRemoteCacheRequired 表示多级缓存缺少远程缓存实例。
	ErrRemoteCacheRequired = xerrors.New("cache: remote cache is required")
)

Functions

This section is empty.

Types

type Distributed added in v0.5.0

type Distributed interface {
	KV
	// HSet 设置 Hash 字段。
	HSet(ctx context.Context, key string, field string, value any) error
	// HGet 读取 Hash 字段;未命中时返回 ErrMiss。
	HGet(ctx context.Context, key string, field string, dest any) error
	// HGetAll 获取整个 Hash;当前仅支持 *map[string]T 目标类型。
	HGetAll(ctx context.Context, key string, destMap any) error
	// HDel 删除一个或多个 Hash 字段。
	HDel(ctx context.Context, key string, fields ...string) error
	// HIncrBy 原子递增整数类型字段。
	HIncrBy(ctx context.Context, key string, field string, increment int64) (int64, error)
	// ZAdd 向有序集合中写入成员。
	ZAdd(ctx context.Context, key string, score float64, member any) error
	// ZRem 从有序集合中删除成员。
	ZRem(ctx context.Context, key string, members ...any) error
	// ZScore 返回成员分数;未命中时返回 ErrMiss。
	ZScore(ctx context.Context, key string, member any) (float64, error)
	// ZRange 按分数升序返回指定区间内成员。
	ZRange(ctx context.Context, key string, start, stop int64, destSlice any) error
	// ZRevRange 按分数降序返回指定区间内成员。
	ZRevRange(ctx context.Context, key string, start, stop int64, destSlice any) error
	// ZRangeByScore 返回指定分数区间内成员。
	ZRangeByScore(ctx context.Context, key string, min, max float64, destSlice any) error
	// MGet 批量读取多个 key;目标必须是切片指针。
	MGet(ctx context.Context, keys []string, destSlice any) error
	// MSet 批量设置多个 key-value。
	MSet(ctx context.Context, items map[string]any, ttl time.Duration) error
	// RawClient 返回底层客户端,用于 Pipeline、Lua 脚本等高级场景。
	RawClient() any
}

Distributed 定义分布式缓存能力。

当前唯一实现基于 Redis。除 KV 语义外,Distributed 还提供 Hash、Sorted Set、Batch 和 RawClient 等 Redis 导向能力。

func NewDistributed added in v0.5.0

func NewDistributed(cfg *DistributedConfig, opts ...Option) (Distributed, error)

NewDistributed 根据配置创建分布式缓存实例。

当前仅支持 Redis,需要通过 WithRedisConnector 显式注入连接器。

type DistributedConfig added in v0.5.0

type DistributedConfig struct {
	// Driver 后端类型,目前仅支持 redis。
	Driver DistributedDriverType `json:"driver" yaml:"driver"`

	// KeyPrefix 全局 Key 前缀。
	KeyPrefix string `json:"key_prefix" yaml:"key_prefix"`

	// Serializer 序列化器类型:"json" | "msgpack"。
	Serializer string `json:"serializer" yaml:"serializer"`

	// DefaultTTL 默认 TTL,当 Set 或 Expire 传入 ttl<=0 时使用。默认 24 小时。
	DefaultTTL time.Duration `json:"default_ttl" yaml:"default_ttl"`
}

DistributedConfig 分布式缓存配置。

type DistributedDriverType added in v0.5.0

type DistributedDriverType string

DistributedDriverType 分布式缓存驱动类型。

type KV added in v0.5.0

type KV interface {
	// Set 设置缓存值。
	Set(ctx context.Context, key string, value any, ttl time.Duration) error
	// Get 读取缓存值;未命中时返回 ErrMiss。
	Get(ctx context.Context, key string, dest any) error
	// Delete 删除缓存值。
	Delete(ctx context.Context, key string) error
	// Has 判断 key 是否存在。
	Has(ctx context.Context, key string) (bool, error)
	// Expire 更新 key 的 TTL;ttl<=0 时使用组件配置的 DefaultTTL;bool=false 表示 key 不存在。
	Expire(ctx context.Context, key string, ttl time.Duration) (bool, error)
	// Close 释放缓存实例拥有的资源。
	Close() error
}

KV 定义缓存组件的稳定 KV 能力。

这是 Local、Distributed 和 Multi 共享的最小公共语义。调用方可以依赖如下约定:

  • Set 在 ttl>0 时使用显式 TTL,在 ttl<=0 时使用组件的 DefaultTTL。
  • Get 未命中时返回 ErrMiss。
  • Delete 删除不存在的 key 不视为错误。
  • Expire 返回值中的 bool 表示 key 是否存在。

type Local added in v0.5.0

type Local interface {
	KV
}

Local 定义本地缓存能力。

Local 面向进程内热点数据,只提供 KV 能力,并承诺值语义: 调用方修改原始对象或读取结果,不应反向污染缓存内部数据。

func NewLocal added in v0.5.0

func NewLocal(cfg *LocalConfig, opts ...Option) (Local, error)

NewLocal 根据配置创建本地缓存实例。

当前默认实现基于 otter,面向进程内热点数据和短路径加速场景。

type LocalConfig added in v0.5.0

type LocalConfig struct {
	// Driver 后端类型,目前仅支持 otter。
	Driver LocalDriverType `json:"driver" yaml:"driver"`

	// MaxEntries 缓存最大条目数。
	MaxEntries int `json:"max_entries" yaml:"max_entries"`

	// Serializer 序列化器类型:"json" | "msgpack"。
	Serializer string `json:"serializer" yaml:"serializer"`

	// DefaultTTL 默认 TTL,当 Set 或 Expire 传入 ttl<=0 时使用。默认 1 小时。
	DefaultTTL time.Duration `json:"default_ttl" yaml:"default_ttl"`
}

LocalConfig 本地缓存配置。

type LocalDriverType added in v0.5.0

type LocalDriverType string

LocalDriverType 本地缓存驱动类型。

type Multi added in v0.5.0

type Multi interface {
	KV
}

Multi 定义多级缓存能力。

Multi 代表一层策略组合,而不是新的存储引擎。它遵循:

  • 读路径:local -> distributed -> backfill local。
  • 写路径:write distributed -> write local。
  • 删路径:delete distributed + delete local。
  • local 与 remote 由调用方持有,Multi 不接管它们的生命周期,Close 也不会关闭它们。

func NewMulti added in v0.5.0

func NewMulti(local Local, remote Distributed, cfg *MultiConfig) (Multi, error)

NewMulti 根据配置创建多级缓存实例。

local 与 remote 是核心依赖,必须显式传入,且它们的生命周期仍由调用方负责。 Multi 不扩展 Hash、Sorted Set 等远程能力,仅提供两级 KV 策略。

type MultiConfig added in v0.5.0

type MultiConfig struct {
	// LocalTTL 写入本地缓存时使用的 TTL。0 表示跟随写入 TTL。
	LocalTTL time.Duration `json:"local_ttl" yaml:"local_ttl"`

	// BackfillTTL 远程回填本地缓存时使用的 TTL,默认 1 分钟。
	BackfillTTL time.Duration `json:"backfill_ttl" yaml:"backfill_ttl"`

	// FailOpenOnLocalError 本地缓存异常时是否继续访问远程缓存。默认 true。
	// 使用指针以区分"未设置"(nil)和"显式设置为 false"。
	FailOpenOnLocalError *bool `json:"fail_open_on_local_error" yaml:"fail_open_on_local_error"`
}

MultiConfig 多级缓存配置。

type Option

type Option func(*options)

Option 缓存组件选项函数。

func WithLogger

func WithLogger(l clog.Logger) Option

WithLogger 注入日志记录器。

func WithMeter

func WithMeter(m metrics.Meter) Option

WithMeter 注入指标 Meter(默认使用 metrics.Discard)。

func WithRedisConnector

func WithRedisConnector(conn connector.RedisConnector) Option

WithRedisConnector 注入 Redis 连接器。

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL