Maison > développement back-end > Golang > le corps du texte

Scénarios de défaillance du cache de fonction Golang et stratégies de traitement

WBOY
Libérer: 2024-05-05 08:00:02
original
361 Les gens l'ont consulté

Dans le langage Go, les scénarios de défaillance du cache de fonctions incluent : les modifications de paramètres, les modifications de variables globales, le redéploiement de programmes et les modifications simultanées. Les stratégies de traitement comprennent : 1. Calcul paresseux (le premier appel pour effectuer des calculs et mettre en cache les résultats) ; 2. Stratégie d'expiration (vérifier régulièrement la validité des résultats mis en cache) ; 3. Mécanisme de notification (s'abonner aux événements ou aux messages pour invalider automatiquement le cache) ; ); 4. Exclure le scénario d'invalidation (modifier la logique du code ou introduire d'autres technologies). Cas pratique : Le site e-commerce utilise une fonction pour obtenir les prix des produits. Il peut utiliser une stratégie d'expiration pour vérifier régulièrement les changements de prix, et utiliser un mécanisme de verrouillage pour empêcher les modifications simultanées.

Scénarios de défaillance du cache de fonction Golang et stratégies de traitement

Scénarios d'échec du cache des fonctions du langage Go et stratégies de traitement

Dans le langage Go, la mise en cache des fonctions peut grandement améliorer les performances du code, mais elle n'est pas parfaite. L'invalidation du cache de fonctions est inévitable. Cet article présentera les scénarios d'invalidation courants et leurs stratégies de gestion.

Scénario d'invalidation

  • Changement de paramètre : Le cache de fonction dépend des paramètres de la fonction. Si les paramètres changent, le cache sera invalide.
  • Modification de variable globale : Si une fonction accède à une variable globale partagée et que la variable est modifiée, le cache sera invalidé.
  • Redéploiement du programme : Une fois le programme redéployé, tous les caches de fonctions seront invalidés.
  • Modification simultanée : Dans un environnement simultané, plusieurs goroutines exécutées simultanément peuvent modifier les données partagées en même temps, provoquant une défaillance du cache.

Stratégie de traitement

1. Calcul paresseux

Le calcul paresseux est une stratégie de calcul paresseux, qui effectue uniquement des calculs et met en cache les résultats lorsque la fonction est appelée pour la première fois. directement depuis le cache.

import "sync"

var m sync.Map

func Fibonacci(n int) int {
    if n < 2 {
        return n
    }

    var result int
    val, exists := m.Load(n)
    if exists {
        result = val.(int)
    } else {
        result = Fibonacci(n-1) + Fibonacci(n-2)
        m.Store(n, result)
    }

    return result
}
Copier après la connexion

2. Stratégie d'expiration

La stratégie d'expiration consiste à vérifier régulièrement si les résultats stockés dans le cache sont toujours valides, et à les supprimer du cache s'ils sont invalides.

import (
    "sync"
    "time"
)

type entry struct {
    value interface{}
    expiry time.Time
}

var cache = sync.Map{}

func SetWithExpiry(key, value interface{}, expiry time.Duration) {
    cache.Store(key, &entry{value: value, expiry: time.Now().Add(expiry)})
}

func Get(key interface{}) (interface{}, bool) {
    val, exists := cache.Load(key)
    if !exists {
        return nil, false
    }
    entry := val.(*entry)
    if entry.expiry.Before(time.Now()) {
        cache.Delete(key)
        return nil, false
    }
    return entry.value, true
}
Copier après la connexion

3. Le mécanisme de notification

peut automatiquement invalider le cache de fonctions en s'abonnant à des événements ou à des messages. Lorsque les données pertinentes changent, un événement ou un message est déclenché pour notifier le cache de l'invalidation.

import (
    "context"
    "sync"
)

var results = sync.Map{}
var invalidations = make(chan struct{})

func Memoize(ctx context.Context, f func() (interface{}, error)) (interface{}, error) {
    key := f
    val, ok := results.Load(key)
    if ok {
        return val.(interface{}), nil
    }

    result, err := f()
    if err != nil {
        return nil, err
    }

    invalidations <- struct{}{} // 触发缓存失效
    results.Store(key, result)
    return result, nil
}
Copier après la connexion

4. Éliminer les scénarios d'échec

Parfois, nous pouvons éliminer les scénarios d'échec en modifiant la logique du code ou en introduisant d'autres techniques. Par exemple, en utilisant des structures de données immuables ou un accès synchrone aux données partagées.

Cas pratique

Supposons que nous soyons sur un site e-commerce et que nous disposions d'une fonction GetProductPrice pour obtenir le prix d'un produit. Étant donné que les prix des produits changent fréquemment, nous devons utiliser la mise en cache des fonctions pour optimiser les performances.

import (
    "sync"
    "time"
)

type product struct {
    ID    int
    Price float64
}

var cache = sync.Map{}

// GetProductPrice 从缓存获取产品价格,如果缓存中没有,则从数据库中获取并缓存
func GetProductPrice(id int) (float64, error) {
    val, exists := cache.Load(id)
    if exists {
        return val.(float64), nil
    }

    product, err := getProductFromDatabase(id)
    if err != nil {
        return 0, err
    }

    cache.Store(id, product.Price)
    return product.Price, nil
}
Copier après la connexion

Étant donné que les prix des produits changent régulièrement, nous devons utiliser une politique d'expiration pour gérer le cache et vérifier régulièrement si le prix a changé.

import (
    "context"
    "sync"
    "time"
)

var cache = sync.Map{}
var invalidations = make(chan struct{})

func GetProductPriceWithExpiry(id int) (float64, error) {
    ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
    defer cancel()

    for {
        val, exists := cache.Load(id)
        if exists {
            entry := val.(*entry)
            if entry.expiry.Before(time.Now()) {
                cache.Delete(id)
            } else {
                return val.(float64), nil
            }
        }

        product, err := getProductFromDatabase(id)
        if err != nil {
            return 0, err
        }

        invalidations <- struct{}{}
        cache.Store(id, &entry{value: product.Price, expiry: time.Now().Add(1 * time.Minute)})
        return product.Price, nil
    }
}
Copier après la connexion

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!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
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
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal