Go (Golang) 中的缓存:Redis 与替代工具

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

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

开始课程

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

推荐