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

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

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

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

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

1 ответ

Решение

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

  1. QuerySets ленивы
  2. Чтобы оценить их, нужно их сериализовать [ссылка]
  3. Не все QuerySet могут быть сериализованы, потому что сериализатор 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"

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

Другие вопросы по тегам