Кеширование результатов запроса Django
Я создаю сайт, используя Django 1.7 и GeoDjango. Я достиг того момента, когда мне нужно оптимизировать скорость сайта.
Одним из узких мест является выполнение запросов. Есть некоторые запросы, которые выполняются медленно даже при оптимизации. Поэтому я хотел бы кэшировать результаты запросов и сохранять их в Redis.
Проблема в том, что я не могу кэшировать некоторые результаты запроса. Особенно те, которые содержат типы геометрии и расчеты расстояния. Я нажал "Ошибка типа: невозможно выбрать двоичные объекты".
Каков рекомендуемый / правильный способ кеширования Django/GeoDjango QuerySets?
1 ответ
Оказывается, основные проблемы при хранении наборов запросов заключаются в том, что:
- QuerySets ленивы
- Чтобы оценить их, нужно их сериализовать [ссылка]
- Не все 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()
Этот метод хорош, потому что данные, хранящиеся в кеше, находятся в ожидаемой текстовой форме. Поэтому не должно быть проблем / исключений при хранении данных.
Основными недостатками являются:
Кэш может содержать повторяющиеся подобные данные. Это может произойти, когда вы кэшируете HTML-фрагмент, содержащий строки языкового перевода и так далее. Поэтому при некоторых обстоятельствах вам придется использовать язык в качестве параметра для генерации кеша. А если у вас есть переводы на 2 языка, у вас будет 2 кэша с одинаковыми данными.
Вам придется аннулировать кэш в ситуациях, когда вы вносите изменения в свой HTML. Это может стать настоящей болью, если HTML-код в блоке кода, который вы кэшируете, постоянно меняется.
Я лично думаю, что проблема 1) не имеет большого значения. Проблему 2) можно избежать, если хорошо спланировать структуру сайта и знать, что в Redis можно выполнить массовую аннулирование ключей кеша. [ссылка] Это возможно, потому что кеш хранится в следующем формате ключа: ":1:template.cache.slow_query.8a5b358dfc28a6bc1b3397e398d28b66"
Так что должна быть возможность удалить все ключи кеша, связанные с каким-то блоком кеширования.