Кэширование файлов Sitemap в django

Я реализовал простой класс sitemap, используя приложение sitemap для 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 

Проблема заключается в том, что memcache позволяет использовать только макс. 1 Мб объекта. Это было больше, чем 1 МБ, поэтому сохранение кэша не удалось:

 >7 SERVER_ERROR object too large for cache 

Проблема в том, что django имеет автоматизированный способ решения, когда он должен делить файл sitemap на небольшие. Согласно документам ( http://docs.djangoproject.com/en/dev/ref/contrib/sitemaps/ ):

Вы должны создать индексный файл, если одно из ваших файлов Sitemap содержит более 50 000 URL-адресов. В этом случае Django автоматически разбивает карту сайта, и индекс будет отражать это.

Как вы считаете, лучший способ включить кэширование sitemaps? – Взлом в каркасе django sitemaps, чтобы ограничить один размер карты сайта, скажем, 10 000 записей, как лучшая идея. Почему было выбрано 50 000 человек? Совет Google? случайное число? – Или, может быть, есть способ разрешить memcached хранить более крупные файлы? – Или, возможно, сохраненные карты, файлы Sitemap должны быть доступны как статические файлы? Это означало бы, что вместо кэширования с memcached мне пришлось бы вручную сохранять результаты в файловой системе и получать их оттуда в следующий раз, когда запрашивается карта сайта (возможно, ежедневная очистка каталога в задании cron).

Все это кажется очень низким, и мне интересно, существует ли очевидное решение …

    50k это не хардкорный параметр. 🙂

    Вы можете использовать этот класс вместо django.contrib.sitemaps.GenericSitemap

     class LimitGenericSitemap(GenericSitemap): limit = 2000 

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

    Если вам нужна очень большая карта сайта и вы хотите использовать 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 ссылками, а также реализовал кеш-файл.

    Основной алгоритм таков:

    • Попробуйте загрузить файл Sitemap из файла на диске
    • Если это не удается, создайте карту сайта и
    • Если файл Sitemap содержит 250 ссылок (число, указанное выше), сохраните его на диске и затем верните.

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

    Код для всего этого здесь, если вам интересно: http://bitbucket.org/mlissner/legal-current-awareness/src/tip/alert/alertSystem/sitemap.py

    Возможно, это будет хорошим решением для вас.

    Вы можете обслуживать файлы Sitemap также в формате gzip, что делает их намного меньше. XML отлично подходит для сжатия gzip. То, что я иногда делаю: создайте файлы (файлы) файла Sitemap в cronjob и визуализируйте их так часто, как это необходимо. Обычно, одного раза в день будет достаточно. Код для этого может выглядеть так. Просто убедитесь, что ваш файл sitemap.xml.gz от вашего корня домена:

      from django.contrib.sitemaps import GenericSitemap from django.contrib.sitemaps.views import sitemap from django.utils.encoding import smart_str import gzip sitemaps = { 'page': GenericSitemap({'queryset': MyModel.objects.all().order_by('-created'), 'date_field': 'created'}), } f = gzip.open(settings.STATIC_ROOT+'/sitemap.xml.gz', 'wb') f.write(smart_str(sitemap(request, sitemaps=sitemaps).render().content)) f.close() 

    Это должно заставить вас начать.