Кэширование файлов Sitemap в Django - PullRequest
9 голосов
/ 17 января 2010

Я реализовал простой класс карты сайта, используя стандартное приложение карты сайта 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 есть автоматизированный способ решить, когда он должен делить файл карты сайта на меньшие. По документам (http://docs.djangoproject.com/en/dev/ref/contrib/sitemaps/):

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

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

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

Ответы [ 4 ]

16 голосов
/ 23 марта 2010

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

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

class LimitGenericSitemap(GenericSitemap):
    limit = 2000
2 голосов
/ 07 декабря 2015

Вы можете обслуживать карты сайта также в формате gzip, что делает их намного меньше. XML идеально подходит для сжатия gzip. Что я иногда делаю: Создайте gzipped файлы (файлы) сайта в 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()

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

2 голосов
/ 27 марта 2010

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

Если вам нужен очень большой файл 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)

1 голос
/ 19 августа 2010

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

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

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

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

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

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

...