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 ¶
- type RedisCache
- func (c *RedisCache[T]) Del(ctx context.Context, key string) error
- func (c *RedisCache[T]) DelBatch(ctx context.Context, keys ...string) error
- func (c *RedisCache[T]) Exists(ctx context.Context, key string) (bool, error)
- func (c *RedisCache[T]) Get(ctx context.Context, key string) (*T, error)
- func (c *RedisCache[T]) GetBytes(ctx context.Context, key string) ([]byte, error)
- func (c *RedisCache[T]) GetOrLoad(ctx context.Context, key string) (*T, error)
- func (c *RedisCache[T]) MGet(ctx context.Context, keys ...string) (map[string]*T, error)
- func (c *RedisCache[T]) Refresh(ctx context.Context, key string) (*T, error)
- func (c *RedisCache[T]) Set(ctx context.Context, key string, value *T) error
- func (c *RedisCache[T]) SetRaw(ctx context.Context, key string, data []byte, ttl time.Duration) error
- func (c *RedisCache[T]) SetWithTTL(ctx context.Context, key string, value *T, ttl time.Duration) error
- type RedisConfig
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]) 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]) 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
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 缓存实例。