Я реализовал простой класс карты сайта с помощью приложения карты сайта django по умолчанию. Поскольку требовалось много времени для выполнения, я добавил ручное кэширование:
class ShortReviewsSitemap(Sitemap):
changefreq = "hourly"
priority = 0.7
def items(self):
# try to retrieve from cache
result = get_cache(CACHE_SITEMAP_SHORT_REVIEWS, "sitemap_short_reviews")
if result!=None:
return result
result = ShortReview.objects.all().order_by("-created_at")
# store in cache
set_cache(CACHE_SITEMAP_SHORT_REVIEWS, "sitemap_short_reviews", result)
return result
def lastmod(self, obj):
return obj.updated_at
Проблема состоит в том, что кэш-память позволяет только макс. объект 1 МБ. Этот был больше что 1 МБ, таким образом храня в отказавший кэш:
>7 SERVER_ERROR object too large for cache
Проблема состоит в том, что django имеет автоматизированный способ решить, когда он должен разделить файл карты сайта на запаха. Согласно документам (http://docs.djangoproject.com/en/dev/ref/contrib/sitemaps/):
Необходимо создать индексный файл, если одна из карт сайта имеет больше чем 50 000 URL. В этом случае Django будет автоматически нумеровать страницы карту сайта, и индекс отразит это.
То, что Вы думаете, было бы лучшим способом позволить кэшировать карты сайта? - Взламывающий django платформу карт сайта для ограничения единственный размер карты сайта, скажем, 10 000 записей походят на лучшую идею. Почему 50,000 был выбран во-первых? Совет Google? случайное число? - Или возможно существует способ позволить memcached, хранят большие файлы? - Или возможно onces сохраненный, карты сайта должны быть сделаны доступными как статические файлы? Это означало бы, что вместо того, чтобы кэшироваться с memcached я должен буду вручную сохранить результаты в файловой системе и получить их оттуда в следующий раз, когда карту сайта требуют (возможно, очистка каталога ежедневно в задании крона).
Все они кажутся очень низким уровнем и я задаюсь вопросом, существует ли очевидное решение...
50k это не хардкорный параметр. :)
Вы можете использовать этот класс вместо django.contrib.sitemaps.GenericSitemap
class LimitGenericSitemap(GenericSitemap):
limit = 2000
Предполагая, что вам не нужны все эти страницы в карте сайта, уменьшите лимит чтобы уменьшить размер файла, все будет нормально, как описано в предыдущем ответе.
Если вам нужна очень большая карта сайта и вы хотите использовать memcached, вы можете разделить контент на несколько частей, сохранить их под отдельными ключами, а затем снова собрать их вместе на выходе. Чтобы сделать это более эффективным, Memcached поддерживает возможность получения нескольких ключей одновременно, хотя я не уверен, поддерживает ли клиент django эту возможность.
Для справки, ограничение в 1 МБ - это особенность memcached, связанная с тем, как он хранит данные: http://code.google.com/p/memcached/wiki/FAQ#What_is_the_maximum_data_size_you_can_store?_ (1_megabyte)
У меня на сайте около 200 000 страниц, поэтому индекс должен был быть у меня, несмотря ни на что. Я закончил тем, что сделал вышеупомянутый хак, ограничив карту сайта до 250 ссылок, а также реализовал файловый кеш.
Базовый алгоритм таков:
Конечным результатом является то, что в первый раз запрашивается карта сайта, если она полная, создается и сохраняется на диск. В следующий раз, когда он будет запрошен, он просто будет загружен с диска. Поскольку мой контент никогда не меняется, это работает очень хорошо. Однако, если я действительно хочу изменить карту сайта, это так же просто, как удалить файл (ы) с диска и дождаться, пока сканеры не восстановят что-то.
Если вам интересно, код для всего этого находится здесь: http://bitbucket.org/mlissner/legal-current-awareness/src/tip/alert/alertSystem/sitemap.py
Возможно, это будет хорошим решением и для вас.