Memorizzazione nella cache dei dati in base al grafico delle dipendenze

1

Il mio team e io stiamo attualmente mantenendo un sistema di caching basato esclusivamente sulle chiavi. Da quello che ho letto stiamo cercando un sistema basato sulla strategia cache-aside. Dove abbiamo un sito web che parla con un servizio di riposo utilizzando httpclients. Questi client utilizzano una memoria cache che funziona in base a una chiave combinata. Quando viene chiamato un altro metodo che invaliderebbe un elemento della cache, dovremmo istruire manualmente il memorycache a rimuoverlo.

Lascia che ti spieghi con l'esempio.

MemoryCacheStore = > oggetto memorizzato in un singleton per l'intera applicazione web (Asp.Net MVC)

Pseudo codice che spiega il caso:

public class CustomerRestClient {
    private readonly IMemoryCacheStore _cacheStore;
    private readonly User user;
    public CustomerRestClient(IMemoryCacheStore cacheStore, User user){
        _cacheStore = cacheStore;
        _user = user;
    }

    public Customer Get(int id){
        return _cacheStore.Get($"Customer-Get-{id}-{_user.Id}", TimeSpan.FromMinute(10), () => RestService.Get(id));
    }

    public Customer Update(Customer customer){
        var newCustomer = RestService.Update(customer);
        _cacheStore.InvalidateKey($"Customer-Get-{customer.id}-{_user.Id});
        return newCustomer;
    }
}

Il problema con questo approccio è che lo sviluppatore deve sapere quali chiavi invalidare ogni volta che un oggetto è cambiato. Stiamo pensando di provare a risolvere questo problema con una sorta di cachekeymanager per eliminare la magia della stringa chiave, ma non risolve il problema che lo sviluppatore deve ancora sapere cosa invalidare quando e queste definizioni sono distribuite in tutti i nostri restclients.

Potresti sostenere che questo non dovrebbe essere un problema e devo ammettere che all'inizio non lo era. Ma man mano che il codebase diventa più grande, gli oggetti cambiano nome, questo sta diventando un incubo di gestione con numerosi bug report come risultato.

Quindi la mia domanda è:
Conoscete eventuali strategie di caching o strutture che posso esaminare per risolvere il nostro caso?

Sto pensando più alla direzione di definire un grafico delle dipendenze e spero che qualcuno abbia già affrontato questo problema che potrebbe darci nuove intuizioni.

    
posta Peter 07.03.2018 - 14:27
fonte

1 risposta

1

Quello a cui ti stai sforzando è un database locale come layer.

Attualmente stai memorizzando i risultati per più azioni (chiamate API) e ti sforzi di nominare in modo univoco tali azioni come chiavi.

Pensando con una mentalità del database o del negozio degli oggetti, è necessario memorizzare le entità / oggetti che sono stati creati, modificati o rimossi come risultato di queste azioni. E devi indirizzare in modo univoco gli oggetti tramite una combinazione di: Type , Id . È inoltre necessario identificare gli oggetti obsoleti in base a Timestamp .

Esistono molte soluzioni di DB incorporate in grado di sincronizzare e incorporare che seguono tale approccio, ad esempio: link o link ecc. Funzionano come cache di oggetti intelligenti.

Per quanto riguarda il problema "ricorda di invalidare la cache", puoi disaccoppiare il codice di modifica dell'oggetto dalla cache usando il modello di evento:

  1. chiamate API che modificano dati, emettono oggetti nuovi, modificati o rimossi come eventi di modifica. Ogni evento ha: Tipo, Id, timestamp e ultimo oggetto / dati. Gli sviluppatori che scrivono tali chiamate API devono solo emettere tutti gli oggetti modificati. Non è necessario chiamare direttamente l'invalidazione della cache.

  2. Cache sottoscrive questi eventi e sincronizza l'oggetto locale db / store.

  3. Chiamate API che devono ottenere un oggetto, interrogare prima la cache specificando tipo di oggetto, id e timestamp. Se l'oggetto cache non esiste o è inattivo, viene effettuata una chiamata di rete e l'oggetto viene emesso come evento.

risposta data 08.03.2018 - 09:16
fonte

Leggi altre domande sui tag