python-Django Celery缓存锁不起作用?

我正在尝试使用Django缓存来实现锁定机制.在Celery官方site中,它声称Django缓存可以很好地工作.但是,以我的经验,它没有用.我的经验是,如果有多个线程/进程几乎在同一时间(接近0.003秒)获取锁,则所有线程/进程都将成功获取锁.对于晚于〜0.003秒获得锁定的其他线程,它将失败.

我是唯一一个经历过这件事的人吗?请尽可能纠正我.

def acquire(self, block = False, slp_int = 0.001):
    while True:
        added = cache.add(self.ln, 'true', self.timeout)

        if added:
            cache.add(self.ln + '_pid', self.pid, self.timeout)
            return True

        if block:
            sleep(slp_int)
            continue
        else:
            return False


# Set Django backend cache to localcache
CACHES = { 
    'default': {
        'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
        'LOCATION': '/dev/shm/django_cache',                                                                                                                                                                                              
    }   
}

解决方法:

问题在于Django无法保证.add()的原子性. .add()是否实际上是原子的取决于您使用的后端.使用FileBasedCache时,.add()不是原子的:

def add(self, key, value, timeout=DEFAULT_TIMEOUT, version=None):
    if self.has_key(key, version):
        return False
    self.set(key, value, timeout, version)
    return True

Worker A执行.add()可以在self.has_key(…)之后但在self.set(…)之前被抢占.工人B一枪执行.add()将会成功设置密钥并返回True.当工作程序A恢复时,它还将设置密钥并返回True.

issue report表示您查看的示例代码假定后端为Memcached.如果您使用Memcached或支持原子.add()的后端,则它应该可以工作.

上一篇:芹菜不运行和弦回调


下一篇:django & celery - 关于并发处理能力和内存使用的小结