2010-11-25 2 views
0

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

Memcached put()/delete() являются асинхронными.
Для конкретных объектов мне нужно, чтобы состояние в кэше отражало состояние БД.
Для этих объектов я собираюсь заблокировать Thread on the Future, возвращенный методом 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() для нескольких объектов или если это значительно снизит производительность вашей системы кэширования?
Могу ли я сделать что-то подобное или я действительно не должен это делать?

Thanks

ответ

2

По-моему, вы неправильно используете кеш. Вы предполагаете, что put() на самом деле преуспевает в том, чтобы помещать данные в кеш, и сразу после блокировки вызова put() данные, которые вы вставляете, - это данные, которые вы возвращаете с помощью get(). Есть несколько проблем с этим:

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

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

+0

как я упомянул set/delete are aschronchronous ..поэтому я не понимаю, как удаление может решить эту проблему, если запрос запроса на кеш запускается до фактического удаления. поскольку они асинхронны. для меня это похоже на то, что ваше решение имеет ту же проблему, что и установка ключа другим объектом. – mickthompson 2010-11-25 13:41:28

Смежные вопросы