Django1.3 проблемы с кешированием нескольких работников gunicorn

у меня странные проблемы с кэшированием в версии 1.3 django. Возможно, я что-то неправильно настроил, но не знаю что.

Хорошим примером является django-avatar, который использует кеширование, и многие его используют. Даже если у меня нет определенного бэкенда кеша, аватар кажется кэшированным, что само по себе было бы нормально, но он продолжает переключаться между последними кэшированными значениями. Пример: Загружаю новую аватарку, теперь примерно в 50% запросов она мне показывает новую, в 50% старую. Если я удалю старый, я все равно получу его на сайте в 50% случаев. Единственный способ исправить это — отключить кеширование аватара, установив его на одну секунду.

Сначала я подумал, что это из-за того, что я использовал django.core.cache.backends.locmem.LocMemCache, который никогда раньше не использовал, но это происходит даже тогда, когда я вообще не настраиваю бэкенд кеша.

Я нашел одну похожую ошибку: ошибка кэширования Django.. даже если кэширование отключено

но мои страницы отображаются нормально, именно теги шаблонов (на данный момент) вызывают проблемы в моей настройке.

Я использую django 1.3, postgres, nginx, gunicorn 0.12.0, greenlet==0.3.1, eventlet==0.9.16

Я только что провел еще несколько тестов и понял, что это происходит только тогда, когда я запускаю gunicorn с помощью файла конфигурации. Если я запускаю его с помощью ./manage.py run_gunicorn, все в порядке. Запуск «gunicorn_django -c deploy/gunicorn.conf.py» вызывает проблемы.

Единственное объяснение, которое я могу придумать, состоит в том, что каждый воркер получает свой собственный кеш (интересно, почему, поскольку я не определял кеш).

Обновление: запуск ./manage.py run_gunicorn -w 4 также вызывает те же проблемы. Поэтому я почти уверен, что несколько рабочих вызывают проблемы, и каждый рабочий кэширует значения отдельно.

Моя конфигурация:

import os
import socket
import sys

PORT = 8000
PROC_NAME = 'myapp_gunicorn'
LOGFILE_NAME = 'gunicorn.log'
TIMEOUT = 3600
IP = '127.0.0.1'
DEPLOYMENT_ROOT = os.path.dirname(os.path.abspath(__file__))
SITE_ROOT = os.path.abspath(os.path.sep.join([DEPLOYMENT_ROOT, '..']))
CPU_CORES = os.sysconf("SC_NPROCESSORS_ONLN")
sys.path.insert(0, os.path.join(SITE_ROOT, "apps"))
bind = '%s:%s' % (IP, PORT)
logfile = os.path.sep.join([DEPLOYMENT_ROOT, 'logs', LOGFILE_NAME])
proc_name = PROC_NAME
timeout = TIMEOUT
worker_class = 'eventlet'
workers = 2 * CPU_CORES + 1

Я также пробовал это без использования «eventlet», но получил те же ошибки.

Спасибо за любую помощь.


person Philipp Wassibauer    schedule 21.06.2011    source источник
comment
переключение на memcache, так как серверная часть кэширования решила мою проблему. однако мне все еще интересно, почему это происходит... если я делаю что-то не так или это ошибка.   -  person Philipp Wassibauer    schedule 21.06.2011


Ответы (1)


Скорее всего, по умолчанию используется кеш в памяти, что означает, что каждый рабочий процесс имеет свою собственную версию кеша в своем собственном пространстве памяти. Если вы нажмете поток 1, вы получите кеш, отличный от потока 3. Nginx распределяет нагрузку между каждым потоком, скорее всего, посредством распределения по циклу, поэтому вы меняете потоки при каждом попадании. Что объясняет ваши дурацкие результаты.

Когда вы выполняете manage.py run_gunicorn, он, скорее всего, работает с одним потоком и, следовательно, только с одним кешем, поэтому вы не видите тех же результатов.

Лучше всего использовать memcached или что-то подобное.

person Ken Cochrane    schedule 21.06.2011
comment
хорошо, вроде того, что я ожидал. это должно быть изменилось в последней версии django... так как это работало раньше. вероятно, было бы хорошо указать это в документации. - person Philipp Wassibauer; 21.06.2011
comment
да, очень ясно. nginx+gunicorn, рекомендуем использовать memcached в качестве кеша. - person hahakubile; 30.07.2014