Кэширование результатов запроса Django

Я создаю веб-сайт, используя Django 1.7 и GeoDjango. Я попал в точку, когда мне нужно оптимизировать скорость сайта.

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

Проблема, которую я получаю, заключается в том, что я не могу кэшировать некоторые результаты запроса. Особенно те, которые содержат типы геометрии и расчеты расстояний. Я столкнулся с ошибкой «TypeError: не могу распарить двоичные объекты».

Каков рекомендуемый/правильный способ кэширования наборов запросов Django/GeoDjango?


person Termos    schedule 01.12.2014    source источник


Ответы (1)


Оказывается, основные проблемы с хранением наборов запросов заключаются в следующем:

  1. QuerySets ленивы
  2. Чтобы оценить их, вам необходимо сериализовать их [ ссылка]
  3. Не все QuerySets можно сериализовать, потому что сериализатор Python (Pickle) имеет свои ограничения [ссылка]

Лучшее решение, которое я нашел, - кэшировать результаты запроса в шаблоне.

Итак, в моем шаблоне «sample.html» я пишу что-то вроде:

{% cache 600 slow_query_results %}
<!-- result of page generation -->
{% endcache %}

И в виду я делаю:

from django.core.cache import cache
from django.core.cache.utils import make_template_fragment_key
...
slow_query_results_key = make_template_fragment_key('slow_query_results')
if not cache.get(slow_query_results_key):
    # return calculated result
    slow_query_results = perform_some_slow_query()

Этот метод хорош, потому что данные, хранящиеся в кеше, имеют ожидаемую текстовую форму. Так что не должно быть проблем/исключений при хранении данных.

Основные недостатки заключаются в том, что:

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

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

Я лично думаю, что проблема 1) не имеет большого значения. Проблемы 2) можно избежать, хорошо спланировав структуру сайта и зная, что вы можете сделать массовую аннулирование ключей кеша в Redis. [ссылка] Это возможно, поскольку кеш хранится в следующем ключевом формате: ":1:template.cache.slow_query.8a5b358dfc28a6bc1b3397e398d28b66"

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

person Termos    schedule 02.12.2014