Ars*_*niy 9 python django memcached caching celery
这是我们目前的情况:
cache_instance = cache.get_cache("cache_entry")静态代码.在调查过程中,我发现错误发生的那一刻会cache_instance.get(key)返回错误的值,尽管get_cache("cache_entry").get(key)在下一行返回正确的值.这意味着错误消失太快或由于某种原因cache_instance对象被破坏.django的缓存线程返回的缓存实例对象不安全吗?MemoryError这些天至少记录了一个我知道,所有这些听起来都像是某种魔法......而且,真的,任何想法如何可能或如何调试这将是非常感激的.
PS:我目前的假设是这与多处理有关:只要在静态代码中创建缓存实例,并且在工作进程分叉之前,这将导致所有工作者共享相同的套接字(这听起来似乎合理吗?)
终于解决了:
from django.core.cache import cache此对象存储预连接的memcached套接字.当您的进程可以动态分叉时,请不要使用它.并且不要使用存储的连接,池和其他.这一直困扰着我一段时间,直到我找到了这个问题和答案。我只是想补充一些我学到的东西。
您可以使用本地 memcached 实例轻松重现此问题:
from django.core.cache import cache
import os
def write_read_test():
pid = os.getpid()
cache.set(pid, pid)
for x in range(5):
value = cache.get(pid)
if value != pid:
print "Unexpected response {} in process {}. Attempt {}/5".format(
value, pid, x+1)
os._exit(0)
cache.set("access cache", "before fork")
for x in range(5):
if os.fork() == 0:
write_read_test()
Run Code Online (Sandbox Code Playgroud)
您可以做的是关闭缓存客户端,就像 Django 在request_finished信号中所做的那样:
https://github.com/django/django/blob/master/django/core/cache/初始化的.py#L128
如果你cache.close()在叉子后面放一个,一切都会按预期进行。
对于 celery,您可以连接到在工作人员分叉并执行后触发的信号cache.close()。
当预加载处于活动状态并且在分叉工人之前初始化缓存时,这也会影响 gunicorn。
对于gunicorn,你可以用post_fork你的gunicorn配置:
def post_fork(server, worker):
from django.core.cache import cache
cache.close()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1743 次 |
| 最近记录: |