Как можно обновить фрагментный кеш, разрешив чтение из кеша во время обновления? - PullRequest
0 голосов
/ 27 января 2010

Есть ли способ обновить кэш фрагментов таким образом, чтобы можно было выполнять чтение из кэша во время обновления?

Я кэширую часть представления html.erb в Rails с блоком cache do .. end в erb.

У меня истекает тот же кеш в контроллере с вызовом expire_fragment(:controller => 'controllername')

Я использую memcached в качестве хранилища кеша фрагментов.

Я могу ошибаться, но похоже, что поведение по умолчанию таково, что в момент вызова expire_fragment фрагмент удаляется из кэша, поэтому другой запрос через доли секунды для этого же фрагмента пропустит кэш.

Что я действительно хотел бы, чтобы чтение из кэша продолжалось до тех пор, пока новый фрагмент не будет вычислен и сохранен в кэшированном, после чего все последующие запросы получат эту новую кэшированную версию.

Этот конкретный фрагмент дорогой для вычисления. Это займет около 7 секунд.

Ответы [ 2 ]

0 голосов
/ 27 января 2010

Вы также можете вычислить новые значения кэшированного значения в фоновом режиме, а затем атомарно переключить считыватели для использования нового значения. Для некоторых приложений это может помочь. Например, это может занять некоторое время, чтобы написать большой файл, который кэшируется. Использование этого метода позволяет записывать новую версию файла, в то время как старая версия все еще обслуживается из кэша. Вот техника:

Используйте номер версии как часть ключа кеша. Это можно сделать с помощью кеша фрагментов или memcache.

Шаги:

  1. Добавить «cache_ver» к соответствующей модели
  2. Включить cache_ver при вычислении ключа для кеша. Помните, что метод фрагмента 'cache' может использовать любую строку.
  3. Чтобы обновить кеш:
    1. вычислить следующее значение cache_ver
    2. вычислить новое значение для кеша и сохранить его в кеше, используя новый cache_ver как часть ключа
    3. обновить cache_ver модели. - при следующем поступлении запроса контроллер будет искать cache_ver, использовать новое значение и возвращать новые результаты
    4. Не забудьте очистить старое кэшированное значение в какой-то момент. Возможно, ночью ....

cache_ver может храниться в mem_cache, если вы хотите, вместо db.

0 голосов
/ 27 января 2010

Я бы предположил, что memcached имеет некоторый механизм для обработки конфликтов чтения и записи.

Эта проблема будет иметь значение только на сайте с очень высоким трафиком.

Редактировать: Нашел вопрос "Is_memcached_atomic?"в memcached FAQ :

Все отдельные команды, отправляемые в memcached, являются абсолютно атомарными.Если вы отправите набор и получение параллельно против одного и того же объекта, они не будут сгущаться друг с другом.Они будут сериализованы, и один будет выполнен раньше другого.Даже в многопоточном режиме все команды являются атомарными.Если нет, то это ошибка:)

Я не думаю, что описанная вами проблема будет большой проблемой.Не вдаваясь во внутренности Rails, в среде Rails с несколькими виртуальными виртуальными машинами все еще возможно, что может произойти ошибка кэширования, но в худшем случае сценарий просто состоит в том, что фрагмент генерируется запросами, которые, как оказалось, имеют точное время.Если ваш фрагмент не будет очень дорогим (секунды, а не миллисекунды), а ваш трафик и инфраструктура будут огромными (несколько экземпляров rails, сотни запросов в секунду), я сомневаюсь, что это будет проблемой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...