mcpField
E
encore-go-cache

encore-go-cache

github.com/encoredev数据与数据库30314 次安装2 天前更新
代码仓库

关于 encore-go-cache

面向 Go 服务开发者的 Encore Go 类型化 Redis 缓存指南,涵盖键空间、过期设置、淘汰策略和缓存操作。

主要功能

  1. 01类型化 Redis 键空间
  2. 02整数与浮点计数器
  3. 03列表与集合操作
  4. 04可配置过期与淘汰策略
  5. 05处理缓存未命中与冲突

适用场景

  1. 01缓存结构化 Go 值
  2. 02跟踪原子请求计数
  3. 03在 Redis 中存储列表或集合

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/encoredev/skills --skill encore-go-cache

安装后在 Claude Code 中输入/encore-go-cache确认已加载。

详细介绍

Encore Go 缓存(Redis)

说明

Encore Go 的缓存是 Redis 的类型化封装。声明一次 cache.Cluster,然后为所需的每种数据结构创建 Keyspace 对象。

Cluster
package mycache

import "encore.dev/storage/cache"

var Cluster = cache.NewCluster("my-cache", cache.ClusterConfig{
    EvictionPolicy: cache.AllKeysLRU,
})

淘汰策略:cache.AllKeysLRU(默认)、cache.NoEviction、cache.AllKeysLFU、cache.AllKeysRandom、cache.VolatileLRU、cache.VolatileLFU、cache.VolatileTTL、cache.VolatileRandom。

Keyspace 类型

每个 keyspace 都有一个键结构(用于根据 KeyPattern 构建 Redis 键)和一个值类型。

package mycache

import (
    "context"
    "time"
    "encore.dev/storage/cache"
)

type TokenKey struct {
    TokenID string
}

// Strings
var Tokens = cache.NewStringKeyspace[TokenKey](Cluster, cache.KeyspaceConfig{
    KeyPattern:    "token/:TokenID",
    DefaultExpiry: cache.ExpireIn(time.Hour),
})

func example(ctx context.Context) {
    _ = Tokens.Set(ctx, TokenKey{TokenID: "abc"}, "value")
    val, err := Tokens.Get(ctx, TokenKey{TokenID: "abc"}) // cache.Miss on miss
    _ = Tokens.Delete(ctx, TokenKey{TokenID: "abc"})
    _ = val
    _ = err
}
// Integers (atomic counters)
type CounterKey struct {
    UserID string
}

var Counters = cache.NewIntKeyspace[CounterKey](Cluster, cache.KeyspaceConfig{
    KeyPattern:    "requests/:UserID",
    DefaultExpiry: cache.ExpireIn(10 * time.Second),
})

func incr(ctx context.Context) {
    count, _ := Counters.Increment(ctx, CounterKey{UserID: "user123"}, 1)
    _, _ = Counters.Decrement(ctx, CounterKey{UserID: "user123"}, 1)
    _ = count
}
// Structs (JSON-encoded)
type ProfileKey struct {
    UserID string
}

type UserProfile struct {
    Name  string
    Email string
}

var Profiles = cache.NewStructKeyspace[ProfileKey, UserProfile](Cluster, cache.KeyspaceConfig{
    KeyPattern:    "profile/:UserID",
    DefaultExpiry: cache.ExpireIn(time.Hour),
})

func setProfile(ctx context.Context) {
    _ = Profiles.Set(ctx, ProfileKey{UserID: "123"}, UserProfile{
        Name: "Alice", Email: "[email protected]",
    })
}
其他 keyspace 类型

均来自 encore.dev/storage/cache:

  • NewFloatKeyspace — float64 值,支持 Increment。
  • NewListKeyspace — 列表值,支持 PushLeft/PushRight/PopLeft/PopRight/GetRange。
  • NewSetKeyspace — 集合值,支持 Add/Remove/Contains/Items。
多字段键模式
type ResourceKey struct {
    UserID       string
    ResourcePath string
}

var ResourceRequests = cache.NewIntKeyspace[ResourceKey](Cluster, cache.KeyspaceConfig{
    KeyPattern:    "requests/:UserID/:ResourcePath",
    DefaultExpiry: cache.ExpireIn(10 * time.Second),
})
过期辅助函数
import (
    "encore.dev/storage/cache"
    "time"
)

cache.ExpireIn(time.Hour)              // relative
cache.ExpireDailyAt(2, 0, 0, time.UTC) // specific UTC time each day
cache.NeverExpire                      // no expiry
cache.KeepTTL                          // keep existing TTL when updating
错误
import "encore.dev/storage/cache"

val, err := keyspace.Get(ctx, key)
if errors.Is(err, cache.Miss) {
    // not in cache
}

err = keyspace.SetIfNotExists(ctx, key, value)
if errors.Is(err, cache.KeyExists) {
    // already there
}

指南

  • 将 cache.Cluster 和 keyspace 声明为包级变量。
  • 选择最具体的 keyspace 类型——计数器使用 IntKeyspace,即可免费获得原子 Increment/Decrement。
  • 未命中时,Get() 返回 cache.Miss;发生冲突时,Replace() 和 SetIfNotExists() 返回 cache.Miss/cache.KeyExists。
  • 本地开发使用带有约 100 个键上限的内存 Redis——不要对其进行负载测试。
  • 对于持久化存储,请改用 encore-go-database(Postgres)或 encore-go-bucket(对象存储)。

评论

支持 Markdown