Go(Golang)中的缓存:Redis 及其他解决方案
缓存是提升 Go 应用程序性能的关键工具之一。它可以减少响应时间,降低数据库和外部 API 的负载。在本文中,我们将探讨 Go 中缓存的主要方法:使用 Redis 作为外部存储、内置的内存缓存以及使用 groupcache 库实现的组缓存。
1. 为什么 Go 需要缓存?
Go 是一种面向高性能的语言,但即使是最快的数据库查询或外部服务调用也可能成为瓶颈。缓存有助于:
- 减少重复请求的延迟。
- 降低数据库和第三方 API 的负载。
- 提高服务器的吞吐量。
- 缓解峰值负载。
2. Redis——分布式缓存
Redis 是 Go 中最流行的外部缓存解决方案。它作为一个内存存储运行,支持 TTL、持久化和复杂数据结构。
在 Go 中连接 Redis
在 Go 中操作 Redis 最常用的库是 go-redis。安装:
go get github.com/redis/go-redis/v9示例:带 TTL 的简单缓存
package main
import ( "context" "fmt" "time" "github.com/redis/go-redis/v9")
var ctx = context.Background()
func main() { rdb := redis.NewClient(&redis.Options{ Addr: "localhost:6379", })
// 设置一个值为 10 秒 TTL err := rdb.Set(ctx, "user:42", `{"name":"Alice"}`, 10*time.Second).Err() if err != nil { panic(err) }
// 获取值 val, err := rdb.Get(ctx, "user:42").Result() if err != nil { fmt.Println("缓存未命中") } else { fmt.Println("缓存命中:", val) }}Redis 中的缓存失效策略
- TTL(生存时间)——到期后自动删除。
- 惰性失效——在更新数据时清除缓存。
- 按键删除——对特定键调用
DEL。 - "Cache-Aside" 模式——应用程序自行管理缓存:先检查 Redis,未命中时从数据库加载并存入缓存。
3. Go 中的内存缓存
对于无需外部依赖的本地缓存,可以使用 Go 的内置结构或专门的库。
使用 sync.Map 的简单内存缓存
package main
import ( "fmt" "sync" "time")
type CacheItem struct { Value interface{} Expiration int64}
type Cache struct { items sync.Map}
func (c *Cache) Set(key string, value interface{}, ttl time.Duration) { c.items.Store(key, CacheItem{ Value: value, Expiration: time.Now().Add(ttl).UnixNano(), })}
func (c *Cache) Get(key string) (interface{}, bool) { item, found := c.items.Load(key) if !found { return nil, false } cacheItem := item.(CacheItem) if time.Now().UnixNano() > cacheItem.Expiration { c.items.Delete(key) return nil, false } return cacheItem.Value, true}
func main() { cache := &Cache{} cache.Set("key1", "value1", 5*time.Second) val, ok := cache.Get("key1") if ok { fmt.Println("找到:", val) }}freecache 库
freecache 是一个高性能的内存库,支持 TTL 且内存占用低。安装:
go get github.com/coocood/freecachecache := freecache.NewCache(100 * 1024 * 1024) // 100 MBcache.Set([]by