Go(Golang)中的缓存:Redis、组缓存和内存缓存

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

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/freecache
cache := freecache.NewCache(100 * 1024 * 1024) // 100 MBcache.Set([]by                    

推荐