Django cache.clear () не работает (LocMemCache, AWS) - PullRequest
1 голос
/ 08 апреля 2019

Фон

У меня есть сайт под управлением Django 2.0 на AWS ElasticBeanstalk. У меня есть несколько просмотров на моем веб-сайте, для расчета которых требуется некоторое время, поэтому я подумал о том, чтобы изучить простое кэширование. Я выбрал LocMemCache, потому что он выглядел как самый быстрый в настройке, отвечающий моим потребностям. (Я использую AWS, поэтому использование Memcached, очевидно, требует ElastiCache, что увеличивает стоимость и требует дополнительных затрат на установку, которых я хотел избежать.)

Представления меняются не часто, и сайт не имеет большого трафика, поэтому я установил длинные таймауты для кешей. Есть три вида, где я включил кэширование:

  1. Отчет, созданный внутри шаблона & ndash; использует кэширование фрагментов шаблона
  2. Список местоположений, запрошенных AJAX и используемых в библиотеке JS & ndash; использует кеширование для каждого вида
  3. Динамически генерируемый двоичный файл для загрузки & ndash; использует кэширование для каждого вида

Кэширование настроено и прекрасно работает.

Данные, входящие в эти представления, добавляются и редактируются другими сотрудниками моей компании, которые используются для того, чтобы их изменения появлялись немедленно. Итак, чтобы ответить на такие вопросы, как «Я обновил эти данные, почему веб-страница не обновилась?» Я хотел создать кнопку «Очистить кэш сервера», доступную для персонала, для принудительного сброса кеша.

Кнопка настроена и работает. Он запрашивает представление, которое вызывает cache.clear() из django.core.cache. Я использовал подход кувалдой cache.clear(), потому что способ указания кеша для отдельного представления в коде кажется немного неуклюжим и запутанным, поэтому подход «очистить все» казался адекватным. И, по крайней мере, он всегда должен «работать» в том смысле, что все данные снова загрузятся.

Проблема

Когда я использую кнопку для вызова cache.clear(), он очищает только кэш фрагмента шаблона. Кажется, он не очищает кэши для каждого просмотра. Зачем?

Согласно Документация Django ,

Будьте осторожны с этим; clear() удалит все из кэша, а не только ключи, установленные вашим приложением.

Так почему же это не касается кэшей для каждого просмотра? Разве предупреждение не указывает на то, что clear() опасно конкретно , потому что это кувалда, и ничто не пощадили? Что мне не хватает?

Использует ли AWS какую-то специальную память, неуязвимую для такого рода отбраковки? (Если это так, то почему фрагменты шаблона успешно очищены?) Я заметил (и нахожу это интересным), что кэш остается даже после развертывания нового образа в той же среде.

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

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

settings.py

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
##        'LOCATION': '',
    },
}

portfolio.html (Кэш # 1 - фрагмент шаблона)

{% load static cache compress %}

...

<div id="total-portfolio-content">
{% cache 7200 portfolio %}{% include 'reports/total_portfolio/report_include.html' %}{% endcache %}
</div>

map/urls.py (Кэш-память № 2 - для просмотра)

from django.conf.urls import include, url

app_name = 'map'
urlpatterns = [
    ## Yes, I know this uses the old-style url(). I have plans to upgrade the entire project.
    url(r'^(?P<tg>[\w-]+)/data.geojson$',
        cache_page(60 * 60 * 12)(
            views.NamedGeoJSONLayerView.as_view(model=FacilityCoord)),
        name='tg-data'),
]

resources/urls/__init__.py (кэш # 3 - для просмотра)

from django.conf.urls import include, url

app_name = 'resources'
urlpatterns = [
    url(r'^download/$',
        cache_page(60 * 60 * 12)(
            views.DownloadMetricXLSX.as_view()),
        name='download'),
]

myadmin/views.py (кнопка очистки кэша)

from django.core.cache import cache

@staff_member_required(login_url=login_url)
def clear_cache(request):
    cache.clear()

    ## And because that doesn't seem to work as advertised, I also tried....
    ## taken from <https://djangosnippets.org/snippets/1080/>
    try:
        cache._cache.clear()  # in-memory caching
        cache._expire_info.clear()
    except AttributeError:
        # I think this only applies to filesystem caching? Just grasping at straws.
        old_freq = cache._cull_frequency
        old_max = cache._max_entries
        cache._max_entries = 0
        cache._cull_frequency = 1
        cache._cull()
        cache._cull_frequency = old_freq
        cache._max_entries = old_max

    return JsonResponse({'success': True})
...