Кеширование Django - это можно сделать превентивно? - PullRequest
5 голосов
/ 28 апреля 2009

У меня есть представление Django, которое получает часть своих данных с внешнего веб-сайта, который я анализирую с помощью urllib2 / BeautifulSoup.

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

Есть ли способ загрузить новые данные так, чтобы ни один пользователь никогда не получал такую ​​задержку? Или это неизбежно?

Обратите внимание, что я на сервере общего хостинга, поэтому помните об этом при ответах.

РЕДАКТИРОВАТЬ: спасибо за помощь до сих пор. Тем не менее, я до сих пор не уверен в том, как мне добиться этого с помощью сценария Python, который я буду вызывать. Базовый тест, который я сделал, показывает, что кеш django не является глобальным. То есть, если я вызываю его из внешнего скрипта, он не видит данные кэша, происходящие в платформе. Предложения?

Еще одно РЕДАКТИРОВАНИЕ: , если подумать, это, вероятно, потому, что я все еще использую кэш локальной памяти. Я подозреваю, что если я переместу кеш в memcached, DB, что угодно, это будет решено.

Ответы [ 4 ]

8 голосов
/ 28 апреля 2009

То есть вы хотите запланировать что-то для запуска с регулярным интервалом? За счет некоторого процессорного времени вы можете использовать это простое приложение .

В качестве альтернативы, если вы можете использовать его, задание cron каждые 5 минут:

*/5 * * * * /path/to/project/refresh_cache.py

Веб-хосты предоставляют различные способы их настройки. Для cPanel используйте Cron Manager. Для Google App Engine используйте cron.yaml. Для всего этого вам необходимо сначала настроить среду в refresh_cache.py.

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

4 голосов
/ 30 апреля 2009

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

Конечно, синтаксический анализ, вероятно, не является вашим узким местом; внешний ввод / вывод есть.

Прежде всего, используйте memcached!

Тогда можно использовать следующую стратегию:

  • Ваш кэшированный объект, который называется A, хранится в кэше с динамическим ключом (например, A_<timestamp>).
  • Другой кэшированный объект содержит текущий ключ для A, называемый A_key.
  • Тогда ваше приложение получит ключ для A, сначала получив значение в A_key
  • Периодический процесс будет заполнять кэш ключами A_<timestamp> и после завершения изменить значение в A_key на новый ключ

Используя этот метод, всем пользователям каждые 5 минут не нужно будет ждать обновления кэша, они просто получат более старые версии, пока не произойдет обновление.

4 голосов
/ 28 апреля 2009

«Я все еще не уверен, как мне добиться этого с помощью сценария python, который я буду вызывать».

Проблема в том, что ваша "значительная задержка в несколько секунд, пока я иду на внешний сайт для анализа новых данных", не имеет никакого отношения к кешу Django.

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

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

Когда пользователь делает запрос, вы уже получаете и анализируете результаты, и все, что вы делаете, представляет.

0 голосов
/ 29 апреля 2009

Вы также можете использовать скрипт python для вызова вашего представления и записи его в файл, а затем передать его статически с помощью lightpd, например:

request = HttpRequest()
request.path = url # the url of your view
(detail_func, foo, params) = resolve(url)
params['gmap_key'] = settings.GMAP_KEY_STATIC
detail = detail_func(request, **params)
out = open(dir + "index.html", 'w')
out.write(detail.content)
out.close()

, затем назовите ваш скрипт cron

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