【问题标题】:How to add an item to a memcached list atomically (in Python)如何以原子方式将项目添加到 memcached 列表中(在 Python 中)
【发布时间】:2014-12-11 01:58:47
【问题描述】:

看看下面我的简单 Python memcached 代码:

import memcache
memcache_client = memcache.Client(['127.0.0.1:11211'], debug=True)
key = "myList"
obj = ["A", "B", "C"]
memcache_client.set(key, obj)

现在,假设我想将一个元素“D”附加到缓存为myList 的列表中,我该如何以原子方式完成它?

我知道这是错误的,因为它不是原子的:

memcache_client.set(key, memcache_client.get(key) + ["D"])

上面的语句包含一个竞争条件。如果另一个线程在正确的时间执行相同的指令,其中一个更新将被破坏。

我该如何解决这种竞争状况?如何以原子方式更新存储在 memcached 中的列表或字典?

【问题讨论】:

  • 可能这就是答案,您应该使用cas()(检查并设置)而不是简单的set()
  • 你使用的是哪个 python memcache 库?
  • @Anentropic:来自我的点子冻结:python-memcached==1.53

标签: python multithreading memcached atomic


【解决方案1】:

这里是python客户端API的对应函数

https://cloud.google.com/appengine/docs/python/memcache/clientclass#Client_cas

这里还有 Guido van Rossum 的 nice tutorial。希望他能比我更好地解释 python 的东西;)

在您的情况下,代码应如下所示:

memcache_client = memcache.Client(['127.0.0.1:11211'], debug=True)
key = "myList"
while True: # Retry loop, probably it should be limited to some reasonable retries
  obj = memcache_client.gets(key)
  assert obj is not None, 'Uninitialized object'
  if memcache_client.cas(key, obj + ["D"]):
    break

整个工作流程保持不变:首先获取一个值(将一些内部信息绑定到一个键),然后修改获取的值,然后尝试在内存缓存中更新它。检查值(实际上是键/值对)的唯一区别是它没有从并行过程同时更改。在后一种情况下,调用失败,您应该从头开始重试工作流程。此外,如果您有一个多线程应用程序,那么每个 memcache_client 实例可能应该是线程本地的。

另外不要忘记,简单的整数计数器有 incr() 和 decr() 方法,它们本质上是“原子的”。

【讨论】:

  • 你能说明我应该如何在上面的案例中使用 cas 语句吗?文档不包含示例。此外,如果可能的话,展示如何(在 python 中)以原子方式将键/值添加到存储在 memcached 中的字典中。
  • 注意 gets/cas 语法略有不同,如果使用 pylibmc sendapatch.se/projects/pylibmc/reference.html
【解决方案2】:

如果您不想收到竞争条件,那么您必须使用线程模块中的 Lock 原语。例如

lock = threading.Lock()

def thread_func():
    obj = get_obj()
    lock.acquire()
    memcache_client.set(key, obj)
    lock.release()

【讨论】:

  • 内存缓存服务器的 other 客户端仍然存在竞争情况
  • @Anentropic Saqib Ali 询问 python 线程而不是多个服务器,所以如果他只使用一个客户端和多个线程,我的回答仍然有效。
猜你喜欢
  • 2023-04-06
  • 1970-01-01
  • 2013-03-07
  • 1970-01-01
  • 2019-11-26
  • 2018-03-28
  • 2013-08-03
  • 1970-01-01
相关资源
最近更新 更多