Memcached - кэширующая информация, которая должна синхронизироваться с БД - PullRequest
0 голосов
/ 25 ноября 2010

Я использую Memcached в качестве системы кэширования и Spymemcached в качестве Java-клиента для хранения моих объектов в кэше.

Memcached put () / delete () являются асинхронными.
Для определенных объектов мне нужно, чтобы состояние в Cache отражало состояние БД.
Для этих объектов яподумав о блокировке потока в будущем, возвращаемого методом spyMemcachedClient.put (), чтобы убедиться, что кэш отражает текущее состояние БД.

что-то вроде

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 () для нескольких типов объектов или это резко снизит производительность моей системы кэширования?
Могу ли я сделать что-то подобное или я не должен этого делать?

Спасибо

1 Ответ

2 голосов
/ 25 ноября 2010

По моему вы используете кеш неправильно. Вы предполагаете, что 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)? Ваш кеш никогда не будет заполнен данными, если вы не обновите каждую статью в вашей системе - что вы, вероятно, очень редко делаете.

Хорошо, надеюсь, это поможет;)

...