如何在多个进程之间共享缓存?

问题描述 投票:9回答:2

我正在使用a LRU cache来加速一些相当重型的处理。它运作良好,可以大大加快速度。然而...

当我进行多处理时,每个进程都创建它自己的独立缓存,并且有8个相同的副本。这似乎不是一个问题,直到盒子耗尽内存并且结果发生了不好的事情......

理想情况下,我只需要一个大约300个项目的cachesize为应用程序,1 * 300将适合我必须使用的7GB,但8 * 300只是不适合。

如何让所有进程共享相同的缓存?

python multiprocessing
2个回答
7
投票

我相信你可以使用Manager在进程之间共享一个dict。从理论上讲,这应该允许您为所有功能使用相同的缓存。

但是,我认为更合理的逻辑是让一个进程通过在缓存中查找它们来响应查询,如果它们不存在,则将工作委托给子进程,并在返回之前缓存结果。你可以很容易地做到这一点

with concurrent.futures.ProcessPoolExecutor() as e:
    @functools.lru_cache
    def work(*args, **kwargs):
        return e.submit(slow_work, *args, **kwargs)

请注意,work将返回Future对象,消费者将不得不等待。 lru_cache将缓存未来的对象,以便它们自动返回;我相信您可以多次访问他们的数据,但现在无法测试它。

如果您不使用Python 3,则必须安装concurrent.futuresfunctools.lru_cache的反向移植版本。


0
投票

将共享缓存传递给每个进程。父进程可以实例化单个缓存并将其作为参数引用到每个进程...

@utils.lru_cache(maxsize=300)
def get_stuff(key):
    return Stuff(key)

def process(stuff_obj):
    # get_stuff(key) <-- remove it from here
    stuff_obj.execute()

def iterate_stuff(keys):
    for key in keys:
        yield get_stuff(key)  # <-- and put it here

def main():
    ...
    keys = get_list_of_keys()
    for result in pool.imap(process, iterate_stuff(keys)):
         evaluate(result)
    ...

Katriel让我走上了正确的轨道,我会实现这个答案,但是,愚蠢的我,这实际上比[应用程序]更容易。

© www.soinside.com 2019 - 2024. All rights reserved.