9

He tomado una clase de base de datos este semestre y estamos estudiando mantener la coherencia de la caché entre el RDBMS y un servidor de caché como memcached. Los problemas de consistencia surgen cuando hay condiciones de carrera. Por ejemplo:Consistencia de la caché al usar memcached y una rdbms como MySQL

  1. Supongamos que hago un get(key) desde la memoria caché y hay una falta de caché. Como recibo una falta de caché, obtengo los datos de la base de datos y luego hago un put(key,value) en el caché.
  2. Pero, podría ocurrir una condición de carrera, donde otro usuario podría eliminar los datos que obtuve de la base de datos. Esta eliminación puede ocurrir antes de hacer un put en la caché.

Por lo tanto, idealmente el put en la memoria caché no debería ocurrir, ya que los datos están más presentes en la base de datos.

Si la entrada de caché tiene un TTL, la entrada en el caché puede caducar. Pero aún así, hay una ventana donde los datos en el caché son inconsistentes con la base de datos.

He estado buscando artículos/trabajos de investigación que hablan sobre este tipo de problemas. Pero no pude encontrar ningún recurso útil.

Respuesta

0

¿Qué le parece usar una variable de guardar en Memcache como señal de bloqueo?

cada comando único Memcache es atómica

después de que ha recuperado los datos de db, palanca de bloqueo en

después de poner los datos a Memcache, conmutar el bloqueo fuera

antes de eliminar de db, comprobar el estado de bloqueo

-1

Cuando se lee, ocurre lo siguiente:

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

Cuando se escribe, ocurre lo siguiente:

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

explica cómo se corrigen las condiciones de carrera mencionadas en la pregunta. su respuesta aparentemente no aborda el problema. – Alexey

0

Este artículo le da una nota interesante sobre cómo Facebook (intenta) mantener la coherencia de caché: http://www.25hoursaday.com/weblog/2008/08/21/HowFacebookKeepsMemcachedConsistentAcrossGeoDistributedDataCenters.aspx

Aquí hay una esencia del artículo.

  1. actualizo mi nombre de pila de "Jason" a "Mono"
  2. Escribimos "mono" en la base de datos maestra en California y borrar mi nombre de Memcache en California, pero no de Virginia
  3. Alguien va al perfil de Virginia
  4. encontramos mi primer nombre en memcache y volvemos "Jason"
  5. replicación se pone al día y actualizar la base de datos de esclavos con mi nombre como "mono."También borrar mi nombre de Virginia Memcache porque ese objeto caché se presentó en el flujo de replicación
  6. Otra persona va al perfil de Virginia
  7. No encontramos mi primer nombre en Memcache así leemos desde el esclavo y obtener "mono"
0

el código siguiente da una idea de cómo utilizar las operaciones de Memcached add, gets y cas para implementar el bloqueo optimista para garantizar la coherencia de caché con la base de datos.
Descargo de responsabilidad: no garantizo que sea perfectamente correcto y maneje todas las condiciones de carrera. También los requisitos de coherencia pueden variar entre las aplicaciones.

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 
Cuestiones relacionadas