Как использовать систему кэширования для больших и динамических данных
Я хочу использовать систему кэширования для моего веб-приложения django, я использовал django-cachepos для кэширования данных, но теперь у меня есть некоторые проблемы, например, большие данные для отчетов, которые включают много фильтров и должны быть онлайн, когда данные обновляются .
Теперь мое время отклика слишком велико (около 12 13 с), и я хочу получить от вас руководство по внедрению системы кэширования или стратегии кэширования, которая может помочь улучшить мой код
Рассмотрите это, что аппликация собирается быть крупномасштабным проектом и прямо сейчас имеет 3 4 свинца от всех интернеров и не может перестать быть онлайн
Ps. У меня есть эта проблема на некоторых других конечных точках с запросами с большим количеством данных
Я пытаюсь использовать функции redis для установки и получения данных, но я понятия не имею, как использовать их с фильтрами и даже кэшировать данные ответа
Похоже, что django-cacheops использует Redis под капотом, который является простым хранилищем ключей/значений. Это означает, что для каждого запроса он будет создавать ключ с закодированными фильтрами и результатами в качестве значения (читайте код в разделе "def _cache_key(...)" здесь). Существует дополнительная логика для определения всех ключей, которые должны быть аннулированы при изменениях (читайте invalidation.py здесь). У вас не будет контроля над этим поведением (например, обновлять результаты кэширования вместо высылки), поэтому рассмотрение других стратегий, скорее всего, будет означать отказ от django-cacheops.
Вы говорите, что все еще получаете длительное время ожидания (запросы 12-13 с), вам нужно больше покопаться, чтобы понять причину. В django-cacheops есть статистика для анализа этого. Вы должны проверить, каков % совпадений и промахов в кэше. Я предполагаю, что вы получаете больше промахов, чем попаданий, учитывая природу динамических данных (ключи аннулируются до того, как они выдают хиты), а также количество фильтров (если последующие запросы уникальны по комбинациям фильтров, вы никогда не получите попадание в кэш и всегда будете запрашивать БД, а не кэш). Ограниченный размер кэша усилит это поведение (меньшее пространство означает большее количество вытеснений, чтобы освободить место для новых запросов).
После этого анализа вам следует обратить внимание на три вещи:
- оставить django-cacheops и поэкспериментировать с применением некоторых или большинства фильтров в коде (отфильтровать более полный/обычный набор результатов после их возвращения из кэша). Хороший пример - если вы всегда запрашиваете данные за последние 30 дней, отправляете только этот фильтр в django-cacheops и применяете другие фильтры в коде, это будет выглядеть примерно так:
qs = Article.objects.filter(created_at__gte=thirty_days_ago).cache()
results = [row for row in qs if apply_filters(row, other_filters)]
- ditch django-cacheops. Рассмотрите возможность использования более оптимизированного Redis datatypes для ваших нужд по получению данных. Вы можете узнать, как устанавливать/получать данные, используя python redis client или django cache, настроенный для вашего проекта.
- полностью отказаться от кэширования ключей/значений и рассмотреть возможность использования другого вторичного хранилища, оптимизированного для более быстрого получения динамических данных. Обратите внимание, что это зависит от данных (структурированные или неструктурированные, временные ряды, насколько "большие данные" вы имеете в виду?). Я подозреваю, что elasticsearch/opensearch будет хорошим вариантом, который стоит рассмотреть, но вы не предоставили достаточно контекста.