Как кешировать страницы, используя фоновые задания? - PullRequest
1 голос
/ 14 мая 2010

Определения: ресурс = коллекция записей базы данных, регенерация = обработка этих записей и вывод соответствующего html

Текущий поток:

  • Получить запрос клиента
  • Проверка ресурса в кеше
  • Если не в кеше или срок действия кеша истек, восстановите
  • Возвращаемый результат

Проблема в том, что шаг регенерации может связать один серверный процесс на 10-15 секунд. Если несколько пользователей запрашивают один и тот же ресурс, это может привести к тому, что пара процессов будет одновременно восстанавливать один и тот же ресурс, каждый из которых займет 10-15 секунд.

Разве не было бы предпочтительным, чтобы во внешнем сигнале был какой-то фоновый процесс, говорящий: «Эй, восстанови мне этот ресурс».

Но что тогда это будет отображать для пользователя? «Перестройка» недопустима. Все ресурсы должны быть в кеше заранее. Это может быть проблемой, поскольку база данных почти дублируется в файловой системе (слишком большой, чтобы поместиться в памяти). Есть ли способ избежать этого? Не идеально, но, похоже, единственный выход.

Но есть еще одна проблема. Как удержать одни и те же два процесса от запроса на восстановление ресурса в одно и то же время? Фоновый процесс может регенерировать ресурс, когда интерфейс запрашивает регенерацию того же ресурса.

Я использую PHP и Zend Framework на тот случай, если кто-то захочет предложить решение для конкретной платформы. Хотя это не так важно - я думаю, что эта проблема относится к любому языку / структуре.

Спасибо!

Ответы [ 5 ]

2 голосов
/ 14 мая 2010

С помощью Varnish вы можете активно кэшировать содержимое страницы и использовать грацию для отображения устаревшего, кэшированного содержимого, если ответ не возвращается вовремя.

Включить льготный период (лак обслуживает устаревшие (но кэшируемые) объекты при извлечении объекта из серверной части)

Возможно, вам придется настроить циферблаты, чтобы определить наилучшие настройки для того, как долго обслуживать устаревший контент и сколько времени нужно, чтобы что-то считалось устаревшим, но это должно работать для вас. Подробнее о производительности лака на вики-странице.

1 голос
/ 15 мая 2010

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

Работа PHP выполняется регулярно (возможно, из CRON), который генерирует информацию в Memcached, который затем используется потенциально сотни раз до он снова восстановлен.

Хотя они кэшируются в течение четко определенных периодов (будь то 60 минут или 1 минута), они регенерируются чаще, чем это. Поэтому, если что-то пойдет не так, у них никогда не истечет срок действия Memcache, потому что более новая версия кэшируется до истечения срока действия. Конечно, вы можете просто договориться о том, чтобы они никогда не истекали.

Я также делал подобные вещи в очереди - вы можете видеть предыдущие вопросы, на которые я ответил относительно BeanstalkD.

1 голос
/ 14 мая 2010

Я рекомендую кэшировать на уровне веб-сервера, а не в приложении

0 голосов
/ 15 мая 2010

Вы описываете несколько проблем, возможно, вам помогут некоторые общие идеи.

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

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

Третья проблема связана с тем, что делать, когда клиент запрашивает данные, которые не кэшированы и должны быть восстановлены. Если данные должны быть полностью регенерированы, вы застрянете, заставляя клиента ждать завершения регенерации, чтобы помочь с длительным временем генерации контента, вы могли бы определить политику для предиктивной предварительной выборки объектов контента в кеш, но для этого требуется метод для определения отношений между объектами контента. , Хотите ли вы обслуживать клиента «восстанавливающей» страницей до тех пор, пока запрошенный контент не станет доступным, действительно зависит от ожиданий вашего клиента. Рассмотрим многоуровневые кэши со сжатыми архивами данных, если регенерацию контента невозможно улучшить с 10-15 секунд.

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

0 голосов
/ 15 мая 2010

В зависимости от содержимого может быть опция jQuery.load (). (Я использовал его для твиттера)

Шаг 1
Показать кэшированную версию канала.

Шаг 2
Обновите содержимое страницы с помощью jQuery.load () и кэшируйте результаты.

.
Таким образом, страница загружается быстро и отображает содержимое в формате up2date (после x сек.)
Но если перестроить / загрузить полную страницу, это не даст приятного пользовательского опыта.

...