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

Я реализовал простой класс sitemap, используя django default sitemap app. Поскольку это заняло много времени, я добавил ручное кэширование:

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 допускает только макс. 1MB-объект. Это было больше, чем 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).

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

Ответ 1

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

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

class LimitGenericSitemap(GenericSitemap):
    limit = 2000

Ответ 2

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

Если вам нужна очень большая карта сайта и вы хотите использовать memcached, вы можете разделить содержимое на несколько кусков, сохранить их под отдельными ключами и затем снова скомпоновать их на выходе. Чтобы сделать это более эффективным, Memcached поддерживает возможность одновременного получения нескольких ключей, хотя я не уверен, поддерживает ли этот клиент django эту возможность.

Для справки ограничение 1 МБ - это свойство memcached для хранения данных: http://code.google.com/p/memcached/wiki/FAQ#What_is_the_maximum_data_size_you_can_store?_(1_megabyte)

Ответ 3

У меня на моем сайте около 200 000 страниц, поэтому я должен был иметь индекс, несмотря ни на что. Я закончил работу над этим взломом, ограничив карту сайта 250 ссылками, а также реализовал кеш файл.

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

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

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

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

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

Ответ 4

Вы можете обслуживать файлы 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()

Это должно помочь вам начать.