自定义图形中的Da机会式缓存

时间:2019-07-09 19:50:18

标签: dask

我有一个自定义DAG,例如:

dag = {'load': (load, 'myfile.txt'),
       'heavy_comp': (heavy_comp, 'load'),
       'simple_comp_1': (sc_1, 'heavy_comp'),
       'simple_comp_2': (sc_2, 'heavy_comp'),
       'simple_comp_3': (sc_3, 'heavy_comp')}

我正在计算键simple_comp_1simple_comp_2simple_comp_3,它们的执行如下,

import dask
from dask.distributed import Client
from dask_yarn import YarnCluster

task_1 = dask.get(dag, 'simple_comp_1')
task_2 = dask.get(dag, 'simple_comp_2')
task_3 = dask.get(dag, 'simple_comp_3')
tasks = [task_1, task_2, task_3]

cluster = YarnCluster()
cluster.scale(3)
client = Client(cluster)
dask.compute(tasks)
cluster.shutdown()

似乎,不进行缓存,这3个键的计算也将导致heavy_comp的计算也达到3倍。并且由于这是一项繁重的计算,因此我尝试从here实现机会缓存,如下所示:

from dask.cache import Cache
cache = Cache(2e9)
cache.register()

但是,当我尝试打印正在缓存的结果时,我什么也没得到:

>>> cache.cache.data
[]
>>> cache.cache.heap.heap
{}
>>> cache.cache.nbytes
{}

我什至尝试将缓存大小增加到6GB,但是没有效果。难道我做错了什么?如何使Dask缓存键heavy_comp的结果?

2 个答案:

答案 0 :(得分:1)

扩展MRocklin的答案,并在问题下方的注释中设置代码格式。

按您期望的那样立即计算整个图形。 heavy_comp仅执行一次,这就是您想要的。请考虑您在由空函数定义完成的注释中提供的以下代码:

def load(fn):
    print('load')
    return fn

def sc_1(i):
    print('sc_1')
    return i

def sc_2(i):
    print('sc_2')
    return i

def sc_3(i):
    print('sc_3')
    return i

def heavy_comp(i):
    print('heavy_comp')
    return i

def merge(*args):
    print('merge')
    return args

dag = {'load': (load, 'myfile.txt'), 'heavy_comp': (heavy_comp, 'load'), 'simple_comp_1': (sc_1, 'heavy_comp'), 'simple_comp_2': (sc_2, 'heavy_comp'), 'simple_comp_3': (sc_3, 'heavy_comp'), 'merger_comp': (merge, 'sc_1', 'sc_2', 'sc_3')}

import dask
result = dask.get(dag, 'merger_comp')
print('result:', result)

它输出:

load
heavy_comp
sc_1
sc_2
sc_3
merge
result: ('sc_1', 'sc_2', 'sc_3')

如您所见,“ heavy_comp”仅打印一次,表明函数heavy_comp仅执行一次。

答案 1 :(得分:0)

Dask核心库中的机会缓存仅适用于单机调度程序,而不适用于分布式调度程序。

但是,如果您一次只计算整个图形,Dask将智能地保留中间值。如果无论您想保留哪些值,也可以查看persist函数。