Обойти отсутствие в memcached истечения группового символа в кэшировании фрагментов Rails - PullRequest
2 голосов
/ 25 октября 2010

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

Для анонимных пользователей это не большая проблема. Я создаю ключи кеша, такие как 'frontpage-new-show' или 'schedule-weekly-forecast-10/24/10', и истекаю их при создании новой записи в модели Show или при показе, который выйдет в течение следующей недели. модифицируется через подметальные машины. Это прекрасно работает.

Моя проблема с пользователями, которые вошли в систему. У каждого из них есть собственное настроенное расписание, поэтому мои ключи выглядят как «schedule-user-jschuur-10/10/24», а jschuur - это имя пользователя для учетной записи. Я понимаю, что с соглашением, основанным на дате, они истекают естественным образом, но я также хочу явно истечь все фрагменты для кэшированных расписаний в течение дня, когда показываются связанные изменения для чего-то в вашем расписании на этот день (или неделю).

Как выясняется, memcached не может выполнить тот тип подстановки, который мне нужен здесь (schedule-user -. * - 10/10/24). Это означает, что мне нужно какое-то решение, которое хранит все ключи, выданные в центральном ключе поиска, в memcached, или чтобы Rails / Ruby каким-то образом делали это внутренне, основываясь на ключах, которые я отправил в memcached для меня.

Я предполагаю, что первое - лучшее решение. Мой вопрос: как мне сделать это наиболее эффективным способом, чтобы я не терял все сэкономленное время, больше не ударяя по БД. Я мог бы просто сохранить массив или хеш в memcached, извлечь все это, перебрать, если есть совпадения, удалить их и сохранить хеш обратно. Звучит так, как будто это может отлично работать для нескольких сотен или даже тысячи пользователей, но действительно ли это лучший путь?

Кто-то уже занимался этой проблемой и выпустил решение?

Одна вещь, которую следует учитывать, заключается в том, что почти все мое кэширование в настоящее время выполняется с помощью операторов в представлении, направленных на подготовленные ActiveRelations запросы, которые еще не выполнялись, как этот:

<% if current_user %>
  <% if current_user.saved_shows_count %>
    <% cache "schedule-user-#{current_user.username}-#{(Time.now + 3.hours).to_date.end_of_week.strftime('%D')}" do %>
      <% if @shows.any? %>
        <%= render :partial => "schedule/schedule", :locals => { :shows => @shows } %>
      <% end %>
    <% end %>
...

Сайт размещен на Heroku, и я использую камень Далли в качестве клиента.

1 Ответ

5 голосов
/ 25 октября 2010

РЕДАКТИРОВАТЬ: Есть некоторые проблемы с этим, как написано с драгоценным камнем Далли, выполнение чтения поднимает "слишком короткие данные маршала" или "неверные данные маршала в памяти кэша". Не уверен, что так и будет.

Хотя и немного хакерский, вы можете использовать пространство имен, а затем увеличить пространство имен, тем самым лишив законной силы все ключи, созданные с его использованием. Для этого сначала установите пространство имен в инициализаторе (или где-либо еще) с помощью Rails.cache.write("frontpage-new-shows-namespace", "1", {:raw => true}). Когда вы устанавливаете каждый кеш, добавьте Rails.cache.read("frontpage-new-shows-namespace") в ключ хеша, где бы вы ни хотели (не имеет значения, где). Срок действия всех ключей кэша, созданных в пространстве имен, так же прост, как и Rails.cache.increment("frontpage-new-shows-namespace", 1). Возможно, вы сможете добавить Rails.cache.read("frontpage-new-shows-namespace") в качестве глобальной переменной, исключив поиск в memcache для создания ключей кэша, а затем обновлять эту переменную всякий раз, когда вы увеличиваете пространство имен кэша.

Удачи, и я надеюсь, что это поможет.

...