2011-06-21 20 views
2

私はdjangoの1.3バージョンで奇妙なキャッシングの問題があります。私はおそらく、何か設定が間違っているかもしれませんが、何がわかりません。Django1.3複数のgunicorn作業者のキャッシュ問題

良い例は、キャッシングを使用するdjango-avatarであり、多くの人がそれを使用しています。キャッシュバックエンドが定義されていなくても、アバターはキャッシュされているように見えますが、それ自体は大丈夫ですが、キャッシュされた最後の値の間で前後に切り替わります。例:新しいアバターをアップロードします。リクエストの約50%が新しいアバターを表示します。新しいアバターを表示すると、新しいアバターの50%が表示されます。私が古いものを削除すると、私はまだサイトの50%を取得します。これを修正する唯一の方法は、アバターを1秒に設定してキャッシングを無効にすることです。

私は前に使用したことのないdjango.core.cache.backends.locmem.LocMemCacheを使用していたと思っていましたが、キャッシュバックエンドを設定しないといけません。

私は1つの同様のバグが見つかりました: Django caching bug .. even if caching is disabled

を私のページは、私のセットアップに問題を引き起こす(今のところ)だけで罰金、そのtemplatetagsをレンダリングします。

私はdjangoの使用1.3、postgresの、nginxの、gunicorn 0.12.0、greenlet == 0.3.1、私はいくつかのより多くのテストを行なったし、それだけで私が起動したときに起こることに気づい0.9.16

eventlet ==設定ファイルを使用して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' を使用せずに、それを試してみましたが、同じエラーを得ました。

ありがとうございました。

+0

キャッシュバックエンドとしてmemcacheに切り替えると、私の問題が解決しました。しかし、私はまだこれがどうして起こっているのか興味があります...もし何かが間違っている、あるいはこれがバグであれば。 –

答えて

6

ほとんどの場合、インメモリキャッシュがデフォルトに設定されている可能性があります。つまり、各ワーカーは、独自のメモリ空間にキャッシュのバージョンを持っています。あなたがスレッド1をヒットした場合、スレッド3とは別のキャッシュが得られます.Nginxは、ラウンドロビン分散を介して各スレッド間で負荷を分散しているので、ヒットごとにスレッドを変更します。あなたの変な結果を説明します。

manage.py run_gunicornを実行すると、ほとんどの場合シングルスレッドで実行される可能性が高くなります。そのため、同じ結果が表示されません。

memcachedなどを使用すると移動する方法です。

+0

ok、私が期待していたもの。それは以前のバージョンのdjangoで変更されているに違いありません。それはおそらくドキュメントでそれを指摘することは良いでしょう。 –

+0

はい、非常に明確です。 nginx + gunicorn、 'memcached'をキャッシュとして使うことをお勧めします。 – hahakubile