Concorrenza della cache: garantisce l'ultima versione nella cache

1

Abbiamo un'app di servizio dati che funziona su grafici di oggetti. Inseriamo alcuni grafici complessi in un livello di memorizzazione nella cache (memoria) come un singolo elemento di dati, in modo da evitare il tempo necessario per recuperare ogni singolo elemento di dati nell'archiviazione su disco al fine di costruire l'intera gerarchia.

Ciò significa che ogni volta che uno qualsiasi degli elementi dei dati cambia, viene attivato un evento di ri-cache, ricaricando tutto nella gerarchia e memorizzando la versione più recente nella cache.

Recentemente abbiamo apportato modifiche al servizio per aumentare la concorrenza delle operazioni asincrone (principalmente I / O di rete) e osservato il comportamento di contesa se più richieste in ingresso hanno apportato aggiornamenti agli elementi essenzialmente nello stesso grafico a oggetti.

Ogni operazione di aggiornamento non è a conoscenza di altri aggiornamenti simultanei. A livello di persistenza dello spazio di archiviazione, l'infrastruttura dispone di data e ora sulle righe di dati; consentendoci di applicare tecniche di concorrenza ottimistiche, assicurando che nessuno stia scrivendo una versione obsoleta dello storage.

Una modifica in qualsiasi oggetto figlio fa sì che l'oggetto radice incrementi un numero di versione, quindi la riscrittura. Durante tale evento, possono verificarsi altri aggiornamenti simultanei per qualsiasi altro oggetto figlio (o anche lo stesso), il che rende difficile stabilire quale versione di root dell'oggetto si suppone abbia realmente (al momento dell'aggiornamento). Ciò che è peggio, e la preoccupazione principale qui, è che a causa della contesa simultanea dei thread per l'attenzione del processore, il tentativo di memorizzazione nella cache di una versione precedente può accadere dopo il tentativo di caching di una versione più recente.

In questo momento abbiamo ridotto al minimo questo comportamento verificando che la versione dell'oggetto root durante un evento di re-cache corrisponda ancora alla versione salvata durante la propria operazione di aggiornamento. Se il numero di versione non è lo stesso, significa che un altro aggiornamento simultaneo lo ha modificato ulteriormente e la re-cache non dovrebbe continuare - lascia che l'ultima operazione di aggiornamento esegua il re-cache.

Ovviamente riduce al minimo le probabilità, ma non elimina a titolo definitivo; può ancora essere possibile per l'oggetto radice conservare il suo numero di versione originale su re-fetch, e mentre recupera tutti gli oggetti figli, succede un altro aggiornamento e per colpo di fortuna (malata) riesce a completare e ri-cache prima di questo il tentativo di riprogrammazione in corso ha completato il suo ciclo.

Per complicare ulteriormente il problema, questo servizio dati viene distribuito come un cluster di server senza conoscenza reciproca dei fratelli.

Stava chiedendo se esiste un modo efficace per gestire gli aggiornamenti simultanei su più thread e server per garantire che la copia memorizzata nella cache sia effettivamente sempre la copia più recente?

    
posta icelava 02.05.2014 - 06:05
fonte

1 risposta

1

Alla fine sembra necessario che il servizio cache abbia bisogno anche di un'implementazione ottimistica della concorrenza.

Invece di scrivere ciecamente qualunque versione "nuova" dell'applicazione ha al livello di cache, è necessario prima recuperare una copia (se memorizzata nella cache) per determinare la versione corrente e chiave di concorrenza ottimistica corrente . p>

es. Couchbase Server fornisce valori CAS; Lo storage BLOB di Azure fornisce ETag.

Se la versione corrente della cache è più recente della versione tentata, il tentativo verrà interrotto da quando è stato sostituito.

Se la versione corrente della cache è precedente, il tentativo della cache procederà con l'ultimo valore della chiave della concorrenza ottimizzata. Se un'altra discussione / operazione separata era stata ricollocata, allora la chiave di concorrenza ottimistica sarebbe cambiata e il tentativo corrente della cache non sarebbe riuscito. In questo caso, dovrebbe recuperare la nuova versione dell'articolo e la chiave di concorrenza ottimistica e ripetere il ciclo.

Questo ovviamente ha il costo di dover sprecare almeno un'operazione di lettura semplicemente per determinare se è sicuro scrivere una nuova versione. Ma dato che la coerenza dei dati è fondamentale, suppongo che sia un prezzo da pagare.

    
risposta data 15.12.2014 - 03:55
fonte

Leggi altre domande sui tag