0

オブジェクトをキャッシュに保存するために、キャッシュシステムとしてMemcachedを使用し、JavaクライアントとしてSpymemcachedを使用しています。

Memcached put()/ delete()は非同期です。
特定のオブジェクトの場合、キャッシュ内の状態がDBのステータスを反映している必要があります。
これらのオブジェクトについては、spyMemcachedClient.put()メソッドによって返される未来のスレッドをブロックして、キャッシュがDBの現在のステータスを反映していることを確認することを考えています。

何かのようなもの

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()で十分な速度でキャッシュにアクセスした場合、オブジェクトが現在のDBステータスを反映していない可能性があります。

いくつかの種類のオブジェクトに対してput()をブロックするのが正しいのか、それともキャッシュシステムのパフォーマンスが劇的に低下するのか疑問に思っています。
私はそのようなことをすることができますか、それとも私は実際にそうすることになっていないのですか?

ありがとう

4

1 に答える 1

2

私の意見では、キャッシュを間違って使用しています。put() が実際にデータをキャッシュに入れることに成功し、put() の呼び出しがブロックされた直後に、入れたデータが get() で返されたデータであると想定しています。これにはいくつかの問題があります。

  1. put() が失敗する可能性があります (ネットワーク エラー、メモリ不足エラーなどにより)
  2. put() は成功するかもしれませんが、より新しい、より優先度の高いデータを入れる必要があるため、入れたデータがフラッシュされる可能性があります
  3. 別のプロセスがデータを put() する可能性があり、おそらく古いデータでさえ

...いくつか挙げると。

したがって、基本的には並行性を認識し、キャッシュに依存しないようにする必要があります。これは、許容できる安全なキャッシュの使用方法です。

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 に答える