2010-11-25 2 views
0

J'utilise Memcached en tant que Caching System et Spymemcached en tant que client java pour stocker mes objets dans le cache.
Memcached - Informations de mise en cache qui doivent être synchronisées avec le DB

Les commandes memcached put()/delete() sont asynchrones.
Pour des objets particuliers, j'ai besoin que l'état dans le cache reflète l'état de la base de données.
Pour ces objets, je pense à bloquer le Thread on the Future renvoyé par la méthode spyMemcachedClient.put() pour être sûr que le cache reflète l'état actuel de la BD.

quelque chose comme

changedObject -> block on Memcached.put() Future .. once it's finished -> writeToDB = every subsequent Memcached.get() object is guaranteed to be in synch with the DB 

Si je ne suis pas Synchronisez et je frappe le cache assez vite avec un spyMemcachedClient.get() il se pourrait que l'objet ne reflète pas l'état actuel DB.

Je me demande s'il est correct de bloquer sur le put() pour quelques types d'objets ou si cela diminuera considérablement les performances de mon système de cache?
Puis-je faire quelque chose comme ça ou je ne suis pas vraiment censé le faire?

Merci

Répondre

2

À mon avis, vous utilisez le mauvais cache. Vous supposez que put() réussit réellement à placer les données dans le cache et que, juste après le blocage de l'appel à put(), les données que vous avez entrées sont celles que vous obtenez avec get(). Il y a quelques problèmes avec ceci:

  1. put() peut échouer (à cause de erreur réseau, sur une erreur de mémoire etc)
  2. de vente() pourrait réussir, mais les données vous mettre en pourrait être rincée parce que plus récente, les données plus hiérarchisé ont besoin d'être mis en
  3. un autre processus pourrait mettre() des données, peut-être même vieux données

... pour n'en nommer que quelques-uns. Donc, fondamentalement, vous devriez être conscient de la concurrence et ne jamais compter sur le cache. Ceci est une façon acceptable et sûr d'utiliser le cache:

public String getArticleText(String uuid) { 

String cacheKey = "article_" + uuid; 
String text = cache.get(cacheKey); 
if (text == null) { 

    text = fetch text from db... 
    cache.put(cacheKey, text); 
} 
} 

En utilisant cette approche, vous pouvez vous assurer que le cache a la dernière version en supprimant simplement l'entrée du cache lors de la mise à jour du texte de l'article (dans cet exemple):

public void updateArticleText(String uuid, String text) { 

update article in db... 
cache.delete("article_" + uuid); 
} 

donc, fondamentalement, vous mettez les données dans le cache au moment de la demande, et non pas lorsque les données sont mises à jour. Parce que ce qui se passerait si vous mettez à jour l'article, alors devez redémarrer le serveur de cache (dans un environnement distribué - très commun pour memcached)? Votre cache ne sera jamais rempli avec des données à moins que vous mettiez à jour chaque article sur votre système - ce que vous faites probablement très rarement.

Ok, j'espère que cela aide;)

+0

comme je l'ai mentionné dans/supprimer sont asnychronous ..donc je ne comprends pas comment supprimer peut résoudre ce problème si une demande d'obtention contre le cache est déclenchée avant que la suppression réelle ait lieu. comme ils sont async. Pour moi, il semble que votre solution rencontre le même problème que la définition de la clé avec un autre objet. – mickthompson

+0

Si vous avez besoin que l'entrée dans le cache soit mise à jour avant que votre application puisse continuer à fonctionner correctement, cela signifie probablement que votre application est elle-même en fonction des données dans le cache, ce qui est la mauvaise façon de faire les choses. Pourquoi avez-vous besoin d'attendre que les données soient supprimées/définies avant de pouvoir continuer? –

+0

Mon application ne dépend pas des données dans le cache. J'utilise le cache normalement, mais je me demande si je peux toujours l'utiliser de manière efficace pour stocker des objets qui doivent toujours être synchronisés avec le statut de la base de données. Il est vital pour l'application que très peu d'objets soient synchronisés avec le db. Comme mis (ou supprimer comme vous le suggérez) sont asynch il n'y a aucun moyen de garantir cela si je ne bloque pas jusqu'à ce que l'opération réelle ait lieu. – mickthompson

Questions connexes