Go (Golang) 中的缓存:Redis 与其他工具
缓存是优化 Web 应用程序和微服务性能的关键机制之一。在 Go (Golang) 生态系统中,有许多用于实现缓存的库,从简单的内存解决方案到基于 Redis 的分布式系统。在本文中,我们将详细分析三种主要方法:内置数据结构 (sync.Map)、流行的内存库 (go-cache, freecache, bigcache) 以及与 Redis 的集成。
1. 内置工具:sync.Map
Go 提供了一个线程安全的 map——sync.Map。它适用于数据量小且更新不频繁的简单缓存。然而,在高负载下其性能不如专门的库。
sync.Map 使用示例:
package main
import ( "fmt" "sync" "time")
func main() { var cache sync.Map
// 写入 cache.Store("user:42", map[string]interface{}{ "name": "Alice", "age": 30, })
// 带检查的读取 if val, ok := cache.Load("user:42"); ok { fmt.Println("缓存找到:", val) }
// 删除 cache.Delete("user:42")
// 带 TTL 的缓存(需要手动实现) cache.Store("session:abc", time.Now().Unix())}缺点: 缺少自动 TTL,操作集有限,频繁写入时可能出现性能问题。
2. 内存库
对于更复杂的场景,请使用专门的库。我们来看三种流行的库:
2.1 go-cache
一个支持 TTL 的简单库。非常适合小型项目。
import "github.com/patrickmn/go-cache"
func main() { c := cache.New(5*time.Minute, 10*time.Minute) // 默认 TTL, 清理间隔
c.Set("key", "value", cache.DefaultExpiration) val, found := c.Get("key") if found { fmt.Println(val) }}2.2 freecache
一个具有固定内存大小的库(无 GC 开销)。支持 TTL 和高性能。
import "github.com/coocood/freecache"
func main() { cache := freecache.NewCache(100 * 1024 * 1024) // 100 MB
cache.Set([]byte("mykey"), []byte("myvalue"), 60) // TTL 60 秒 val, err := cache.Get([]byte("mykey")) if err == nil { fmt.Println(string(val)) }}2.3 bigcache
针对存储大量数据且无 GC 暂停进行了优化。适用于序列化数据。
import "github.com/allegro/bigcache/v3"
func main() { cache, _ := bigcache.NewBigCache(bigcache.DefaultConfig(10 * time.Minute))
cache.Set("key", []byte("value")) val, _ := cache.Get("key") fmt.Println(string(val))}3. Redis:分布式缓存
对于分布式系统和微服务,Redis 仍然是事实上的标准。在 Go 中,请使用 go-redis/redis 库 (v9+)。
连接与基本操作:
import ( "context" "fmt" "github.com/redis/go-redis/v9")
func main() { ctx := context.Background() rdb := redis.NewClient(&redis.Options{ Addr: "localhost:6379", Password: "", DB: 0, })
// 设置带 TTL 的值 err := rdb.Set(ctx, "user:42", `{"name":"Bob"}`, 10*time.Minute).Err() if err != nil { panic(err) }
// 读取 val, err := rdb.Get(ctx, "user:42").Result() if err == redis.Nil { fmt.Println("缓存未找到") } else if err != nil { panic(err) } else { fmt.Println("值:", val) }}Go 中 Redis 的高级功能:
- Pipeline