Maison >développement back-end >Golang >Comment gérer l'invalidation du cache Golang ?

Comment gérer l'invalidation du cache Golang ?

WBOY
WBOYoriginal
2024-06-02 17:09:02671parcourir

Lorsque vous traitez l'invalidation du cache dans Golang, vous pouvez suivre la stratégie suivante : marquer les éléments du cache avec des horodatages et obtenir de nouvelles données lorsqu'ils expirent. À l'aide de verrous, le cache est verrouillé lorsque la coroutine obtient l'élément de cache, et le cache est déverrouillé et de nouvelles données sont obtenues lorsque l'élément de cache n'existe pas ou expire.

如何处理 Golang 缓存失效的情况?

Comment gérer l'échec du cache Golang ?

Lors de l'utilisation du cache dans les programmes Golang, il est crucial de gérer les défaillances du cache pour garantir la cohérence et la fiabilité des données. Voici deux stratégies de traitement :

1. Utilisez des horodatages

  • pour associer les éléments du cache aux horodatages.
  • Lorsque l'élément du cache expire, obtenez de nouvelles données et mettez à jour le cache.
type CacheItem struct {
    Value interface{}
    Timestamp time.Time
}

var cache = make(map[string]CacheItem)

func SetCache(key string, value interface{}) {
    cache[key] = CacheItem{Value: value, Timestamp: time.Now()}
}

func GetCache(key string) (interface{}, bool) {
    item, ok := cache[key]
    if ok && time.Since(item.Timestamp) < time.Second*30 {
        return item.Value, true
    }
    return nil, false
}

2. Utiliser des verrous

  • Lorsqu'une coroutine obtient des éléments de cache, verrouillez le cache.
  • Si l'élément du cache n'existe pas ou a expiré, déverrouillez le cache et obtenez de nouvelles données.
var cache = sync.Map{}

func SetCache(key string, value interface{}) {
    cache.Store(key, value)
}

func GetCache(key string) (interface{}, bool) {
    if value, ok := cache.Load(key); ok {
        return value, true
    }

    lock := sync.Mutex{}
    lock.Lock()
    defer lock.Unlock()

    if value, ok := cache.Load(key); ok {
        return value, true
    }

    newValue, err := fetchNewValue(key)
    if err == nil {
        cache.Store(key, newValue)
    }

    return newValue, err == nil
}

Cas pratique

Supposons que nous utilisions le cache dans une API RESTful pour stocker les détails de l'utilisateur.

package main

import (
    "encoding/json"
    "fmt"
    "net/http"
    "time"

    "github.com/go-redis/redis/v8"
)

var redisClient = redis.NewClient(&redis.Options{})

type User struct {
    ID   int
    Name string
}

func main() {
    // 添加缓存处理
    http.HandleFunc("/users/:id", func(w http.ResponseWriter, r *http.Request) {
        var user User
        id := r.URL.Path[len("/users/"):]

        // 尝试从缓存中获取用户数据
        cachedUser, ok := GetCache(id)
        if ok {
            // 缓存命中
            fmt.Fprintf(w, "User from cache: %+v", cachedUser)
            return
        }

        // 缓存未命中
        // 从数据库中获取用户数据
        err := db.Get(id, &user)
        if err != nil {
            // 数据库中不存在此用户
            fmt.Fprintf(w, "User not found")
            return
        }

        // 设置缓存,有效期为 30 秒
        SetCache(id, user, time.Second*30)
        fmt.Fprintf(w, "User from database: %+v", user)
    })

    http.ListenAndServe(":8080", nil)
}

func GetCache(key string) (User, bool) {
    result, err := redisClient.Get(key).Bytes()
    if err != nil {
        return User{}, false
    }

    var user User
    err = json.Unmarshal(result, &user)
    if err != nil {
        return User{}, false
    }

    return user, true
}

func SetCache(key string, user User, expiration time.Duration) {
    jsonBytes, err := json.Marshal(user)
    if err != nil {
        return
    }

    err = redisClient.Set(key, jsonBytes, expiration).Err()
    if err != nil {
        return
    }
}

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn