Golang Redis客户端库使用指南

Golang Redis客户端库使用指南 大家好,

我一直在寻找一个类似于Redisson的、支持内置缓存策略的Go语言Redis客户端库。Go-redis不像Redisson那样通过配置就能直接支持缓存策略。请问是否有具备类似功能支持的Go Redis客户端?请予以说明。

1 回复

更多关于Golang Redis客户端库使用指南的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Go语言中,虽然没有完全等同于Redisson的库,但可以通过组合一些库来实现类似的内置缓存策略功能。以下是一个使用go-redis配合ristretto缓存库实现缓存策略的示例:

package main

import (
    "context"
    "fmt"
    "time"

    "github.com/go-redis/redis/v8"
    "github.com/dgraph-io/ristretto"
)

type CacheClient struct {
    redisClient *redis.Client
    localCache  *ristretto.Cache
}

func NewCacheClient(redisAddr string) *CacheClient {
    // 初始化Redis客户端
    redisClient := redis.NewClient(&redis.Options{
        Addr: redisAddr,
    })

    // 初始化本地缓存(使用Ristretto)
    localCache, err := ristretto.NewCache(&ristretto.Config{
        NumCounters: 1e7,     // 键跟踪数量
        MaxCost:     1 << 30, // 最大缓存成本(1GB)
        BufferItems: 64,      // 缓冲区大小
    })
    if err != nil {
        panic(err)
    }

    return &CacheClient{
        redisClient: redisClient,
        localCache:  localCache,
    }
}

// 带缓存策略的Get方法
func (c *CacheClient) GetWithCache(ctx context.Context, key string, ttl time.Duration) (string, error) {
    // 1. 先尝试从本地缓存获取
    if val, found := c.localCache.Get(key); found {
        return val.(string), nil
    }

    // 2. 本地缓存未命中,从Redis获取
    val, err := c.redisClient.Get(ctx, key).Result()
    if err != nil {
        return "", err
    }

    // 3. 将结果存入本地缓存
    c.localCache.SetWithTTL(key, val, 1, ttl)

    return val, nil
}

// 带缓存策略的Set方法
func (c *CacheClient) SetWithCache(ctx context.Context, key string, value interface{}, ttl time.Duration) error {
    // 1. 设置到Redis
    err := c.redisClient.Set(ctx, key, value, ttl).Err()
    if err != nil {
        return err
    }

    // 2. 同时更新本地缓存
    c.localCache.SetWithTTL(key, value, 1, ttl)

    return nil
}

func main() {
    ctx := context.Background()
    cacheClient := NewCacheClient("localhost:6379")

    // 设置缓存(自动同步到本地缓存)
    err := cacheClient.SetWithCache(ctx, "user:1001", "John Doe", 10*time.Minute)
    if err != nil {
        panic(err)
    }

    // 获取缓存(先查本地缓存,未命中再查Redis)
    val, err := cacheClient.GetWithCache(ctx, "user:1001", 10*time.Minute)
    if err != nil {
        panic(err)
    }

    fmt.Printf("Cached value: %s\n", val)
}

对于更高级的缓存策略,可以使用go-cache库实现TTL和逐出策略:

import (
    "github.com/patrickmn/go-cache"
)

type AdvancedCacheClient struct {
    redisClient *redis.Client
    goCache     *cache.Cache
}

func NewAdvancedCacheClient(redisAddr string) *AdvancedCacheClient {
    // 初始化go-cache,设置默认过期时间和清理间隔
    goCache := cache.New(5*time.Minute, 10*time.Minute)

    return &AdvancedCacheClient{
        redisClient: redis.NewClient(&redis.Options{Addr: redisAddr}),
        goCache:     goCache,
    }
}

// 实现读写穿透策略
func (c *AdvancedCacheClient) ReadThrough(ctx context.Context, key string, fetchFunc func() (string, error), ttl time.Duration) (string, error) {
    // 先查本地缓存
    if val, found := c.goCache.Get(key); found {
        return val.(string), nil
    }

    // 缓存未命中,执行获取函数
    val, err := fetchFunc()
    if err != nil {
        return "", err
    }

    // 更新各级缓存
    c.goCache.Set(key, val, ttl)
    c.redisClient.Set(ctx, key, val, ttl)

    return val, nil
}

如果需要分布式锁功能,可以配合使用redsync库:

import (
    "github.com/go-redsync/redsync/v4"
    "github.com/go-redsync/redsync/v4/redis/goredis/v8"
)

func (c *CacheClient) WithDistributedLock(key string, ttl time.Duration, fn func() error) error {
    pool := goredis.NewPool(c.redisClient)
    rs := redsync.New(pool)
    
    mutex := rs.NewMutex(key, redsync.WithExpiry(ttl))
    
    if err := mutex.Lock(); err != nil {
        return err
    }
    defer mutex.Unlock()
    
    return fn()
}

这些组合方案提供了类似Redisson的缓存策略功能,包括本地缓存、TTL管理、读写穿透和分布式锁等特性。

回到顶部