9

Ho preso una classe di database in questo semestre e stiamo studiando il mantenimento della coerenza della cache tra RDBMS e un server cache come memcached. I problemi di coerenza sorgono quando ci sono condizioni di gara. Ad esempio:Consistenza cache durante l'utilizzo di memcached e rdbms come MySQL

  1. Supponiamo di fare un get(key) dalla cache e c'è un errore di cache. Perché ottengo un errore di cache, recupero i dati dal database e quindi eseguo il put(key,value) nella cache.
  2. Tuttavia, potrebbe verificarsi una condizione di competizione, in cui altri utenti potrebbero eliminare i dati recuperati dal database. Questa eliminazione potrebbe accadere prima di fare un put nella cache.

Quindi, idealmente il put nella cache non dovrebbe accadere, poiché i dati sono più presenti nel database.

Se la voce di cache ha un TTL, la voce nella cache potrebbe scadere. Ma ancora, c'è una finestra in cui i dati nella cache sono incoerenti con il database.

Sono stato alla ricerca di articoli/documenti di ricerca che parlano di questo tipo di problemi. Ma non sono riuscito a trovare alcuna risorsa utile.

risposta

0

Come utilizzare una variabile salvata in memcache come segnale di blocco?

ogni singolo comando memcache è atomico

dopo aver recuperato i dati dal db, levetta di bloccaggio sul

dopo aver messo i dati a memcache, toggle blocco off

prima di cancellare dal db, controllare lo stato di blocco

-1

Quando si legge, accade quanto segue:

if(Key is not in cache){ 
    fetch data from db 
    put(key,value); 
}else{ 
    return get(key) 
} 

Quando si scrive, accade quanto segue:

1 delete/update data from db 
2 clear cache 
+0

Spiegare come sono corrette le condizioni di gara citate nella domanda. la tua risposta apparentemente non affronta il problema. – Alexey

0

Questo articolo fornisce una nota interessante su come Facebook (prova a) mantenere la coerenza della cache: http://www.25hoursaday.com/weblog/2008/08/21/HowFacebookKeepsMemcachedConsistentAcrossGeoDistributedDataCenters.aspx

Ecco un succo da questo articolo.

  1. aggiorno il mio primo nome da "Jason" a "Monkey"
  2. Scriviamo "Monkey" per il database master in California e cancellare il mio nome da memcache in California, ma non Virginia
  3. Qualcuno va al mio profilo in Virginia
  4. troviamo il mio primo nome in memcache e ritorno "Jason"
  5. replica raggiunge e abbiamo aggiornare il database slave con il mio primo nome come "Monkey."Abbiamo anche cancellare il mio nome di battesimo da Virginia memcache perché questo oggetto cache presentò nel flusso replica
  6. Qualcun altro va al mio profilo in Virginia
  7. Noi non troviamo il mio primo nome in memcache così si legge dallo slave e ottenere "Monkey"
0

il codice qui sotto dà un'idea di come usare le operazioni di Memcached add, gets e cas per attuare il blocco ottimistico per garantire la coerenza della cache con la banca dati.
Disclaimer: non garantisco che sia perfettamente corretto e gestisca tutte le condizioni di gara. Anche i requisiti di coerenza possono variare tra le applicazioni.

def read(k): 
    loop: 
    get(k) 
    if cache_value == 'updating': 
     handle_too_many_retries() 
     sleep() 
     continue 
    if cache_value == None: 
     add(k, 'updating') 
     gets(k) 
     get_from_db(k) 
     if cache_value == 'updating': 
     cas(k, 'value:' + version_index(db_value) + ':' + extract_value(db_value)) 
     return db_value 
    return extract_value(cache_value) 

def write(k, v): 
    set_to_db(k, v) 
    loop: 
    gets(k) 
    if cache_value != 'updated' and cache_value != None and version_index(cache_value) >= version_index(db_value): 
     break 
    if cas(k, v): 
     break 
    handle_too_many_retries() 

# for deleting we can use some 'tumbstone' as a cache value