Help us shape the future of Go! Take the 2026 Go Developer Survey

cache

package
v0.10.8 Latest Latest
Warning

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

Go to latest
Published: Oct 29, 2026 License: MIT Imports: 8 Imported by: 0

Documentation

Overview

Package cache 提供基于 go-redis 的 Cache[T] 分布式缓存实现。

与根包内存实现(LocalCache)的关系:根包 data/cache 只保留接口 (Cache/CacheAside/SourceFunc)与内存实现,本子包是 Redis 后端—— import 根包不再传递编译依赖 go-redis。

import (
	"github.com/oekit/pkg/cache"
	rediscache "github.com/oekit/redisx/cache"
)

c := rediscache.NewRedisCache[User](rdb, rediscache.RedisConfig[User]{
    Prefix: "app:user:",
    TTL:    10 * time.Minute,
    Source: loadUserFromDB, // Cache-Aside 未命中回源
})
// c 满足 cache.Cache[User] / cache.CacheAside[User]

接口契约:RedisCache 对 data/cache 门面接口的满足由编译期断言固化 (redis.go 顶部 var 块,int/string 双类型实例化);跨实现一致的通用 缓存语义(miss 非 error、null marker 防穿透、Del 幂等、Refresh、并发 混合等)由 github.com/oekit/pkg/cache/cachetest 契约套件固化,本包 contract_suite_test.go 接入(8 场景 × string/结构体双值类型)。

空值缓存语义(防穿透)见 RedisConfig.NullTTL 字段注释,与 LocalCache 保持一致:0 = 默认开启(1 分钟),负值 = 显式禁用。

null 标记保留前缀契约:null 标记哨兵以 \x00 开头(见 redis.go nullValue),合法 JSON 序列化输出不会自然撞上该前缀。SetRaw 等原始 写入入口不得写入以 \x00 开头的值——精确等于哨兵的条目按 null marker 处理,其余 \x00 开头值不认作 null(走反序列化,默认 JSON 下报错)。 v0.4.0 前哨兵为 "__NULL__",可被 SetRaw 精确碰撞(已废弃)。

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type RedisCache

type RedisCache[T any] struct {
	// contains filtered or unexported fields
}

RedisCache 是基于 Redis 的泛型缓存实现。 实现 Cache[T] 接口,当配置了 Source 时还实现 CacheAside[T] 接口。

func NewRedisCache

func NewRedisCache[T any](client redis.UniversalClient, cfg RedisConfig[T]) *RedisCache[T]

NewRedisCache 创建一个基于 Redis 的泛型缓存实例。

func (*RedisCache[T]) Del

func (c *RedisCache[T]) Del(ctx context.Context, key string) error

Del 删除缓存。

func (*RedisCache[T]) DelBatch

func (c *RedisCache[T]) DelBatch(ctx context.Context, keys ...string) error

DelBatch 批量删除缓存。 空 keys 为幂等 no-op(不报错)——Redis DEL 要求至少 1 个 key,裸 DEL 会报 wrong number of arguments,此处显式短路对齐 cachetest 契约。

func (*RedisCache[T]) Exists

func (c *RedisCache[T]) Exists(ctx context.Context, key string) (bool, error)

Exists 检查缓存是否存在。

func (*RedisCache[T]) Get

func (c *RedisCache[T]) Get(ctx context.Context, key string) (*T, error)

Get 获取缓存(纯缓存查询,不自动回填)。 返回 (nil, nil) 表示数据不存在 — 包括 key 不存在和命中 null marker 两种情况。 调用方需要 null marker 区分时使用 Exists 或 GetRaw。

func (*RedisCache[T]) GetBytes

func (c *RedisCache[T]) GetBytes(ctx context.Context, key string) ([]byte, error)

GetBytes 获取原始字节数据(不经过序列化)。

func (*RedisCache[T]) GetOrLoad

func (c *RedisCache[T]) GetOrLoad(ctx context.Context, key string) (*T, error)

GetOrLoad 获取缓存,未命中时通过 Source 加载并回填(Cache-Aside 模式)。 必须配置 Source 函数,否则等同于 Get。

命中 null marker 时直接返回 (nil, nil),**不会**再调 Source, 避免对不存在的 key 形成 thundering-herd 击穿。

func (*RedisCache[T]) MGet added in v0.7.0

func (c *RedisCache[T]) MGet(ctx context.Context, keys ...string) (map[string]*T, error)

MGet 批量获取(管道一次往返,契约见 pkg/cache.BatchGetter——缺席语义 与 (nil, nil) 双关一致:不存在与 null marker 一律缺席;纯读不回填、 不触发 Source)。反序列化失败按整批错误处理(与单键 Get 同口径)。 缺席键的消费方应回退 GetOrLoad——真 miss 回源回填,marker 命中在 本实现的 GetOrLoad 内短路,两种情况都不会重复回源。

func (*RedisCache[T]) Refresh

func (c *RedisCache[T]) Refresh(ctx context.Context, key string) (*T, error)

Refresh 刷新缓存(删除后重新从 Source 加载)。 必须配置 Source 函数。

func (*RedisCache[T]) Set

func (c *RedisCache[T]) Set(ctx context.Context, key string, value *T) error

Set 设置缓存。

func (*RedisCache[T]) SetRaw

func (c *RedisCache[T]) SetRaw(ctx context.Context, key string, data []byte, ttl time.Duration) error

SetRaw 设置原始字节数据(不经过序列化)。

契约约束:data 不得以 \x00 开头——该前缀保留为 null 标记(见 nullValue)。 写入精确等于哨兵的字节会被读路径按 null marker 处理(Get/GetBytes 返回 nil、GetOrLoad 不回源);写入其他 \x00 开头值属违反契约,不认作 null, 走反序列化(默认 JSON 下报错)。

func (*RedisCache[T]) SetWithTTL

func (c *RedisCache[T]) SetWithTTL(ctx context.Context, key string, value *T, ttl time.Duration) error

SetWithTTL 设置缓存(自定义 TTL)。

type RedisConfig

type RedisConfig[T any] struct {
	// Prefix key 前缀,如 "app:user:"。
	Prefix string

	// TTL 缓存过期时间。默认 24 小时。
	TTL time.Duration

	// Source 缓存未命中时的数据获取函数(Cache-Aside 模式)。
	// 返回 (nil, nil) 表示数据不存在(会缓存空值防穿透)。
	Source cache.SourceFunc[T]

	// Serializer 自定义序列化函数。默认使用 JSON。
	Serializer func(*T) ([]byte, error)

	// Deserializer 自定义反序列化函数。默认使用 JSON。
	Deserializer func([]byte, *T) error

	// NullTTL 空值缓存过期时间(防穿透)。
	//   - 0(未设置):使用默认值 1 分钟;
	//   - 负值:显式禁用空值缓存(Source 返回 nil 时不写 null marker,
	//     下次 GetOrLoad 会重新调用 Source);
	//   - 正值:按指定时长缓存 null marker。
	NullTTL time.Duration
}

RedisConfig 配置 Redis 缓存实例。

Jump to

Keyboard shortcuts

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