2011-06-21 3 views
2

J'ai des problèmes de mise en cache bizarre avec la version 1.3 de django. J'ai probablement quelque chose de mal configuré, mais je ne sais pas quoi.Django1.3 plusieurs travailleurs gunicorn problèmes de mise en cache

Un bon exemple est django-avatar, qui utilise la mise en cache et beaucoup de gens l'utilisent. Même si je n'ai pas de backend de cache défini, l'avatar semble être mis en cache, ce qui serait correct en soi, mais il continue de basculer entre les dernières valeurs mises en cache. Exemple: je télécharge un nouvel avatar, maintenant sur environ 50% des demandes il me montrera le nouveau, 50% l'ancien. Si je supprime l'ancien, je le reçois toujours sur le site 50% du temps. La seule façon de le réparer est de désactiver la mise en cache de l'avatar en le réglant à une seconde. D'abord je pensais que c'était parce que j'ai utilisé django.core.cache.backends.locmem.LocMemCache, que je n'ai jamais utilisé auparavant, mais il arrive même quand je ne configure pas du tout un cache backend.

J'ai trouvé un bug similaire: Django caching bug .. even if caching is disabled

mais mes pages rendent très bien, ses templatetags les (pour l'instant) qui causent les problèmes dans ma configuration.

J'utilise django 1.3, Postgres, nginx, gunicorn 0.12.0, Greenlet == 0.3.1, eventlet == 0.9.16

Je viens de faire un peu plus de tests et réalisé qu'il ne se produit que quand je commence gunicorn en utilisant le fichier de configuration. Si je commence avec ./manage.py run_gunicorn tout va bien. L'exécution de "gunicorn_django -c deploy/gunicorn.conf.py" provoque les problèmes. La seule explication que je peux penser est que chaque travailleur obtient son propre cache (je me demande pourquoi, puisque je n'ai pas défini de cache).

Mise à jour: l'exécution de ./manage.py run_gunicorn -w 4 provoque également les mêmes problèmes. Par conséquent, je suis presque certain que les travailleurs multiples causent les problèmes et chaque travailleur met en cache les valeurs séparément.

Ma configuration:

J'ai essayé aussi
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 

sans utiliser 'eventlet', mais a obtenu les mêmes erreurs.

Merci pour toute aide.

+0

Passer à memcache en tant que backend de mise en cache a résolu mon problème. Cependant, je suis toujours intéressé par ce qui se passe ... si je fais quelque chose de mal ou si c'est un bug. –

Répondre

6

Il est très probable que ce soit par défaut dans le cache en mémoire, ce qui signifie que chaque worker a sa propre version du cache dans son propre espace mémoire. Si vous frappez le fil 1, vous obtenez un cache différent, puis le fil 3. Nginx répartit la charge entre chaque fil probablement par l'intermédiaire d'une distribution à tour de rôle, de sorte que vous changez de fil à chaque coup. Ce qui explique vos résultats farfelus. Lorsque vous gérez manage.py run_gunicorn, il est très probable qu'il exécute un seul thread, et donc un seul cache, et c'est pourquoi vous ne voyez pas les mêmes résultats. L'utilisation de memcached ou de quelque chose de similaire est la voie à suivre.

+0

ok, genre de ce que je m'attendais. ça doit avoir changé dans la dernière version de django ... puisque ça fonctionnait avant. il serait probablement bon de le signaler dans la documentation. –

+0

oui, très clair. nginx + gunicorn, recommande d'utiliser 'memcached' comme cache. – hahakubile

Questions connexes