gpt4 book ai didi

多个线程共享的 Python 内存数组(想想进程空间中的 memcached)

转载 作者:太空宇宙 更新时间:2023-11-04 06:29:30 25 4
gpt4 key购买 nike

所以我有一个多线程程序,简而言之,它下载网页,处理它们并存储结果。它用于处理网页的规则和其他内容存储在数据库中。最初,数据库完全崩溃了(处理每个网页需要向数据库发出 1-50 次请求)。第 1 步是在 memcached 中缓存此信息(如果域没有规则,它只会返回一个空字符串“”),这是一个巨大的改进,与为每个处理的项目敲打数据库 1-50 次相比。但我仍在研究 memcached,它增加了网络延迟(每个处理的项目有 1-50 次往返,加起来很快,即使在本地以太网上也是如此)。

所以我想将结果缓存在进程空间的数组中,基本上是在内存中复制 memcached。数据方面还不错,我将使用 Python 集来基本上复制键:值存储(足够简单)。

但事情是这样的:通常一堆线程会访问同一个站点并且需要相同的规则集,所以我想防止雷群问题(即 10 个线程都试图获取 example.com 的规则,如果不在本地缓存中,而不是在 memcached 中,将导致数据库受到攻击,虽然不是很严重,但有点)。

  1. 设置一个线程(“update_thread”)来更新内存数组,有一个工作队列,如果线程无法从本地缓存中获取域的规则,它会将域写入工作队列,并且休眠几秒钟然后再次尝试,休眠并再次尝试,直到本地内存缓存有一个空字符串“”或一组要使用的规则。线程“update_thread”读取工作队列并从 memcached 获取规则,如果不存在,则从数据库获取规则,并将它们写入 memcached 和本地缓存(如果没有规则,则在值中传播一个空字符串“”)。这样做的缺点是添加了一个线程;更多的 GIL 争用,轻微的延迟(我们必须等待 update_thread 运行,因为我们受 GIL 的支配)。再加上另一个线程和工作队列增加了复杂性。只有“update_thread”可以写入内存缓存数组,因此不需要锁定等。

  2. 我们使用锁来控制对内存中缓存数组的写访问。如果线程找不到规则集,它会尝试从 memcached 获取规则集,如果不在其中,它会访问数据库,一旦找到规则,它就会锁定内存数组并写入规则(或空字符串“”对于值)到内存缓存。缺点:我们可能仍然有雷群问题,但这可以通过为一个域写入一个特殊的值来抵消,例如“获取规则,等一下”,这会导致其他线程等待。

还有谁能想到其他解决方案,或者对我提出的两个解决方案发表评论吗?我怀疑我会选择第 2 种方法,因为锁定 + “获取规则,稍等片刻”似乎比添加线程和工作队列更简单。还是我错过了一些非常明显和简单的解决方案?

最佳答案

如果我理解正确的话,问题是多个线程倾向于同时从 memcached 检索相同的数据。您希望协调线程,以便一个线程检索数据,而其他线程等待,并在数据到达后共享数据。

为要缓存的对象制作一个包装器类。在开始通过网络检索值之前,在缓存中放置一个空包装器。如果另一个线程查找相同的数据,它将阻塞直到值到达。

这是包装器对象:

class PendingValue(object):
def __init__(self):
self._event = threading.Event()

def get(self):
self._event.wait()
return self._value

def set(self, value):
self._value = value
self._event.set()

这是缓存:

class Cache(object):
def __init__(self):
self._dict = {}
self._lock = threading.Lock()

def __getitem__(self, key):
self._lock.acquire()
try:
pv = self._dict[key]
self._lock.release()
return pv.get()
except KeyError: #key not in cache
pv = PendingValue()
self._dict[key] = pv
self._lock.release()
value = retrieve_value_from_external_source()
pv.set(value)
return value

关于多个线程共享的 Python 内存数组(想想进程空间中的 memcached),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4721285/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com