Кэширование набора запросов Django для календарной даты

У меня есть запрос, результаты которого меняются только один раз в день. Кажется пустой тратой времени выполнять этот запрос каждый раз, когда я получаю запрос для этой страницы. Я исследую использование memcached для этого.

Как бы я начал? У кого-нибудь есть предложения или подводные камни, которых следует избегать при использовании кэширования Django? Должен ли я кэшировать в шаблоне или в представлении?

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

Разработка

Пер Кен Кокрейн:

  1. Как часто эти данные меняются: соответствующие данные будут заблокированы для этой календарной даты. Так, например, я извлеку данные за 30 января 2011 г., и я могу обслуживать эту кэшированную копию в течение всего дня до 31 января 2011 г., когда она будет обновлена.

  2. Использую ли я эти данные более чем в одном месте? Только в одном представлении.

  3. Сколько данных это будет: В среднем 10 объектов модели, которые содержат около 15 полей, самое большое из которых — CharField(max_length=120). Я уменьшу количество полей с помощью values() примерно до половины из них.


person Belmin Fernandez    schedule 27.01.2011    source источник


Ответы (2)


Обычно, прежде чем решить, где делать кэширование, я задаю себе несколько вопросов.

  1. Как часто эти данные меняются
  2. Использую ли я эти данные более чем в одном месте?
  3. Сколько данных будет

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

  1. у вас есть представление, которое либо принимает дату, либо использует текущую дату для запроса к базе данных, чтобы извлечь все события календаря для этой даты.
  2. вы отображаете эту информацию только в одном шаблоне,
  3. Объем данных не слишком велик (менее 100 записей).

С этими предположениями у вас есть 3 варианта. 1. кэшировать шаблоны 2. кэшировать представление 3. кэшировать набор запросов

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

Самый простой способ кэширования набора запросов, который я нашел, - это сделать это в ModelManger для рассматриваемой модели. Я бы создал такой метод, как get_calender_by_date(date), который будет обрабатывать запрос и кеширование для меня. Вот грубый макет

CACHE_TIMEOUT_SECONDS = 60 * 60 * 24 # this is 24 hours

class CalendarManager(models.Manager):

    def get_calendar_by_date(self, by_date):
        """ assuming date is a datetime object """
        date_key = by_date.strftime("%m_%d_%Y")
        cache_key = 'CAL_DATE_%s' % (date_key)
        cal_date = cache.get(cache_key)
        if cal_date is not None:
            return cal_date

        # not in cache get from database
        cal_date = self.filter(event_date=by_date)

        # set cal_date in cache for later use
        cache.set(cache_key, cal_date, CACHE_TIMEOUT_SECONDS)
        return cal_date

Некоторые вещи, на которые следует обратить внимание при кэшировании

  1. Убедитесь, что объекты, которые вы храните в кеше, можно замариновать.
  2. Поскольку memcache не знает, какой сегодня день, вам нужно убедиться, что вы не переборщите с кешем. Например, если это был полдень 21 января, и вы кешируете на 24 часа, эта информация календаря будет отображаться до полудня 22 января, и это может быть не то, что вы ищете, поэтому убедитесь, что при установке времени запроса вы либо установите для него небольшое значение, чтобы оно истекало быстрее, либо вы вычисляете, как долго кэшировать, чтобы оно истекало, когда вы хотите, чтобы оно истекло.
  3. Убедитесь, что вы знаете размер объектов, которые хотите кэшировать. Если ваш экземпляр memcache имеет только 16 МБ памяти, но вы хотите хранить 32 МБ данных, кеш не принесет вам много пользы.

При кэшировании шаблона или представления вам необходимо следить за следующим

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

Надеюсь, это даст вам достаточно информации для начала. Удачи.

person Ken Cochrane    schedule 30.01.2011
comment
+1 за отличный обширный ответ. Что касается ваших предположений: вы правы: у вас есть представление, которое либо принимает дату, либо использует текущую дату. Это правильно. Я использую текущую дату для извлечения элементов. Вы находитесь на деньгах на других 2 предположениях. Еще раз спасибо! Я подожду некоторое время для других предложений, но ценю ваш быстрый ответ. - person Belmin Fernandez; 31.01.2011

Попробуйте прочитать это в первую очередь. У Django есть возможность {% кэшировать for_seconds something %} Просто используйте тег cache. http://docs.djangoproject.com/en/dev/topics/cache/

person Alexander A.Sosnovskiy    schedule 27.01.2011
comment
Как бы я установил его для даты календаря? - person Belmin Fernandez; 30.01.2011