0

我使用Memcached作为缓存系统,使用Spymemcached作为 java 客户端来将我的对象存储在缓存中。

Memcached put()/delete() 是异步的。
对于特定对象,我需要缓存中的状态反映数据库的状态。
对于这些对象,我正在考虑阻止 spyMemcachedClient.put() 方法返回的 Future 上的线程,以确保缓存反映数据库的当前状态。

就像是

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

如果我不同步并且我使用 spyMemcachedClient.get() 足够快地访问缓存,则可能是该对象没有反映当前的数据库状态。

我想知道为几种对象阻止 put() 是否正确,或者这是否会大大降低我的缓存系统性能?
我可以做这样的事情还是我真的不应该这样做?

谢谢

4

1 回答 1

2

在我看来,您使用的缓存错误。您假设 put() 实际上成功地将数据放入缓存中,并且在阻塞对 put() 的调用之后,您放入的数据就是您使用 get() 返回的数据。这样做有几个问题:

  1. put() 可能会失败(因为网络错误、内存不足错误等)
  2. put() 可能会成功,但您放入的数据可能会被刷新,因为需要放入更新的、优先级更高的数据
  3. 另一个进程可能会放入()数据,甚至可能是旧数据

...仅举几例。

所以基本上你应该意识到并发性并且永远不要依赖缓存。这是使用缓存的可接受且安全的方式:

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);
 }
}

使用这种方法,您可以通过在更新文章文本时简单地删除缓存条目来确保缓存具有最新版本(在此示例中):

public void updateArticleText(String uuid, String text) {

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

所以基本上,您在请求时将数据放入缓存,而不是在数据更新时。因为如果更新文章会发生什么,然后必须重新启动缓存服务器(在分布式环境中 - 对于 memcached 来说很常见)?除非您更新系统上的每篇文章,否则您的缓存永远不会被数据填充——您可能很少这样做。

好的,我希望这会有所帮助;)

于 2010-11-25T12:43:29.743 回答