Strategie di caching - Amazon ElastiCache

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

Strategie di caching

Nel seguente argomento, puoi trovare strategie per popolare e mantenere la cache.

L'implementazione di strategie per il popolamento e la gestione della cache dipende dal tipo di dati che desideri memorizzare e dai modelli di accesso a tali dati. Ad esempio, probabilmente non utilizzerai la stessa strategia per la classifica dei 10 migliori punteggi di gioco in un sito di gaming, o per le notizie più interessanti. Nella parte restante di questa sezione, discuteremo delle strategie più comuni di gestione della cache, dei loro vantaggi e svantaggi.

Caricamento lento

Come dice lo stesso nome, il caricamento lento è una strategia di caching che consente di caricare i dati nella cache solo quando necessario. Funziona come descritto di seguito.

Amazon ElastiCache è un archivio chiave-valore in memoria che si colloca tra la tua applicazione e il datastore (database) ai quali può accedere. Ogni qualvolta la tua applicazione richieda dati, esso invia per prima cosa la richiesta alla cache ElastiCache. Se i dati sono presenti nella cache e sono correnti, ElastiCache restituisce tali dati all'applicazione. Se i dati non sono presenti nella cache o sono scaduti, l'applicazione richiede i dati al Data Store. L'archivio dati restituisce quindi i dati all'applicazione. Successivamente, l'applicazione scrive i dati ricevuti dall'archivio nella cache. In questo modo, può essere recuperato più rapidamente la prossima volta che viene richiesto.

Un’occorrenza della cache si verifica quando i dati sono presenti nella cache e non sono scaduti:

  1. L'applicazione richiede i dati alla cache.

  2. La cache restituisce i dati all'applicazione.

Una mancato riscontro nella cache si verifica quando i dati non sono presenti nella cache o sono scaduti:

  1. L'applicazione richiede i dati alla cache.

  2. La cache non dispone dei dati richiesti e restituisce un null.

  3. L'applicazione richiede e riceve i dati dal database.

  4. L'applicazione aggiorna la cache con i nuovi dati.

Vantaggi e svantaggi del caricamento lento

I vantaggi del caricamento lento sono i seguenti:

  • Solo i dati richiesti vengono memorizzati nella cache.

    Poiché la maggior parte dei dati non viene mai richiesta, il caricamento lento evita di riempire la cache con i dati non richiesti.

  • Gli errori dei nodi non sono fatali per l'applicazione.

    Se un nodo restituisce un errore e viene sostituito da un nuovo nodo vuoto, l'applicazione continua a funzionare, nonostante l'aumento della latenza. Quando le richieste vengono effettuate al nuovo nodo, ogni mancato riscontro nella cache comporta una query del database. Allo stesso tempo, la copia dei dati viene aggiunta alla cache in modo che le richieste successive vengano richiamate dalla cache.

Gli svantaggi del caricamento pigro sono i seguenti:

  • Comporta una penalità per mancato riscontro nella cache. Ogni mancato riscontro nella cache comporta tre passaggi:

    1. Richiesta iniziale dei dati dalla cache

    2. Query del database per i database

    3. Scrittura dei dati sulla cache

    Questi mancati riscontri possono causare un notevole ritardo dei dati destinati all'applicazione.

  • Dati obsoleti.

    Se i dati vengono scritti nella cache solo quando si verifica un mancato riscontro nella cache, i dati nella cache diventano obsoleti. Questo risultato si verifica perché non sono stati aggiornati alla cache quando i dati vengono modificati nel database. Per risolvere questo problema, è possibile utilizzare il Write-Through e strategie Aggiunta di TTL.

Esempio di pseudocodice di caricamento pigro

Il codice seguente è un esempio di pseudo codice della logica di caricamento lento.

// ***************************************** // function that returns a customer's record. // Attempts to retrieve the record from the cache. // If it is retrieved, the record is returned to the application. // If the record is not retrieved from the cache, it is // retrieved from the database, // added to the cache, and // returned to the application // ***************************************** get_customer(customer_id) customer_record = cache.get(customer_id) if (customer_record == null) customer_record = db.query("SELECT * FROM Customers WHERE id = {0}", customer_id) cache.set(customer_id, customer_record) return customer_record

Per questo esempio, il codice dell'applicazione che ottiene i dati è il seguente.

customer_record = get_customer(12345)

Write-Through

La strategia di scrittura contemporanea aggiunge i dati o li aggiorna nella cache ogni qualvolta i dati vengano scritti sul database.

Vantaggi e svantaggi della scrittura contemporanea

I vantaggi di write-through sono i seguenti:

  • I dati nella cache non sono mai obsoleti.

    Poiché i dati nella cache vengono aggiornati ogni volta che vengono scritti sul database, i dati nella cache sono sempre correnti.

  • Penalità di scrittura e penalità di lettura.

    Ogni scrittura comporta due passaggi:

    1. Una scrittura sulla cache

    2. Una scrittura sul database

    Che aggiunge latenza al processo. Detto questo, gli utenti finali sono generalmente più tolleranti della latenza durante l'aggiornamento o il richiamo dei dati. Esiste la convinzione che gli aggiornamenti comportino maggior lavoro e richiedano pertanto tempi lunghi.

Gli svantaggi di write-through sono i seguenti:

  • Dati mancanti.

    Se si esegue un giro verso l'alto di un nuovo nodo, dovuto a un errore del nodo o a un dimensionamento orizzontale, i dati mancanti sono stati visualizzati. Questi dati continuano a mancare fino a quando non vengono aggiunti o aggiornati nel database. È possibile ridurre al minimo questo implementando caricamento lentocon write-through.

  • Abbandono della cache.

    La maggior parte dei dati non viene mai letta, il che è uno spreco di risorse. Da aggiunta di un valore durata (TTL), è possibile ridurre gli sprechi di spazio.

Esempio di pseudocodice write-through

Il codice seguente è un esempio di pseudo codice della logica di wright-through.

// ***************************************** // function that saves a customer's record. // ***************************************** save_customer(customer_id, values) customer_record = db.query("UPDATE Customers WHERE id = {0}", customer_id, values) cache.set(customer_id, customer_record) return success

Per questo esempio, il codice dell'applicazione che ottiene i dati è il seguente.

save_customer(12345,{"address":"123 Main"})

Aggiunta di TTL

Il caricamento lento accetta i dati obsoleti, ma non restituisce errori con i nodi vuoti. La scrittura contemporanea garantisce dati sempre aggiornati ma può restituire un errore con i nodi vuoti e può popolare la cache con dati superflui. Aggiungendo un valore durata (TTL) a ogni scrittura, puoi avere i vantaggi di ogni strategia. Allo stesso tempo, puoi in gran parte evitare di ingombrare la cache con dati extra.

La durata (TTL) è un valore intero che specifica il numero di secondi fino alla scadenza della chiave. Memcached specifica questo valore in secondi. Quando un'applicazione tenta di leggere una chiave scaduta, viene trattata come se la chiave non fosse mai stata trovata. Il database viene interrogato per la chiave e la cache viene aggiornata. Questo approccio non garantisce che un valore non sia obsoleto. Tuttavia, impedisce ai dati di diventare troppo obsoleti e richiede che i valori nella cache vengano occasionalmente aggiornati dal database.

Per ulteriori informazioni, consulta il comando Memcached set.

Esempi di pseudocodice TTL

Il codice seguente è un esempio di pseudo codice della logica di write-through con TTL.

// ***************************************** // function that saves a customer's record. // The TTL value of 300 means that the record expires // 300 seconds (5 minutes) after the set command // and future reads will have to query the database. // ***************************************** save_customer(customer_id, values) customer_record = db.query("UPDATE Customers WHERE id = {0}", customer_id, values) cache.set(customer_id, customer_record, 300) return success

Il codice seguente è un esempio di pseudo codice della logica di caricamento lento con TTL.

// ***************************************** // function that returns a customer's record. // Attempts to retrieve the record from the cache. // If it is retrieved, the record is returned to the application. // If the record is not retrieved from the cache, it is // retrieved from the database, // added to the cache, and // returned to the application. // The TTL value of 300 means that the record expires // 300 seconds (5 minutes) after the set command // and subsequent reads will have to query the database. // ***************************************** get_customer(customer_id) customer_record = cache.get(customer_id) if (customer_record != null) if (customer_record.TTL < 300) return customer_record // return the record and exit function // do this only if the record did not exist in the cache OR // the TTL was >= 300, i.e., the record in the cache had expired. customer_record = db.query("SELECT * FROM Customers WHERE id = {0}", customer_id) cache.set(customer_id, customer_record, 300) // update the cache return customer_record // return the newly retrieved record and exit function

Per questo esempio, il codice dell'applicazione che ottiene i dati è il seguente.

save_customer(12345,{"address":"123 Main"})
customer_record = get_customer(12345)

Argomenti correlati