【问题标题】:Django Celery cache lock did not work?Django Celery 缓存锁不起作用?
【发布时间】:2016-01-27 10:33:34
【问题描述】:

我正在尝试使用 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',                                                                                                                                                                                              
    }   
}

【问题讨论】:

    标签: python django celery


    【解决方案1】:

    问题在于 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
    

    执行.add() 的Worker A 可以在self.has_key(...) 之后但self.set(...) 之前被抢占。 Worker B 一次性执行.add() 将成功设置密钥并返回True。当worker A恢复时,它也会设置key并返回True

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

    【讨论】:

    猜你喜欢
    • 2018-11-12
    • 2018-09-17
    • 2017-10-08
    • 2011-12-19
    • 2019-04-07
    • 2014-11-24
    • 2019-03-27
    • 1970-01-01
    相关资源
    最近更新 更多