慢慢增加Dask Sheduler的内存使用量

时间:2017-10-04 14:54:44

标签: dask dask-distributed

我正在进行测试:

client = Client('127.0.0.1:8786')

def x(i):
    return {}

while True:
    start = time.time()
    a = client.submit(randint(0,1000000))
    res = a.result()
    del a
    end = time.time()
    print("Ran on %s with res %s" % (end-start, res))

client.shutdown()
del client

我使用它(使用更多代码)来估计我的查询性能。但是对于这个例子,我已经删除了所有我能想到的东西。

上面的代码每秒泄漏大约0.1 MB,我估计每1000次调用大约0.3 MB。

我在代码中做错了吗?

2 个答案:

答案 0 :(得分:1)

我的python调试技巧有点生疏(有点我的意思是我上次在2009年使用Orbited(websockets的前身)上使用objgraph)但是从我所看到的,检查引用数量之前和之后:

在使用objgraph.show_most_common_types()

之前和之后计算调度程序中的对象
| What        | Before           | After  |  Diff   |  
|-------------+------------------+--------|---------+
| function    | 33318            | 33399  |   81    | 
| dict        | 17988            | 18277  |   289   |  
| tuple       | 16439            | 28062  | 11623   | 
| list        | 10926            | 11257  |  331    | 
| OrderedDict | N/A              | 7168   | 7168|

在任何情况下都不是大量的RAM,但是深入挖掘我发现t scheduler._transition_counter是11453并且scheduler.transition_log被填充:

 ('x-25ca747a80f8057c081bf1bca6ddd481', 'released', 'waiting', 
      OrderedDict([('x-25ca747a80f8057c081bf1bca6ddd481', 'processing')]), 4121), 
 ('x-25ca747a80f8057c081bf1bca6ddd481', 'waiting', 'processing', {}, 4122), 
 ('x-25cb592650bd793a4123f2df39a54e29', 'memory', 'released', OrderedDict(), 4123), 
('x-25cb592650bd793a4123f2df39a54e29', 'released', 'forgotten', {}, 4124), 
 ('x-25ca747a80f8057c081bf1bca6ddd481', 'processing', 'memory', OrderedDict(), 4125), 
 ('x-b6621de1a823857d2f206fbe8afbeb46', 'released', 'waiting', OrderedDict([('x-b6621de1a823857d2f206fbe8afbeb46', 'processing')]), 4126)

我的第一个错误
这当然让我意识到我的第一个错误是没有配置transition-log-length。

将配置transition-log-length设置为10后:

| What           | Before   | After  |  Diff   | 
| ---------------+----------+--------+---------|
| function       | 33323    | 33336  |  13     |
| dict           | 17987    | 18120  |  133    | 
| tuple          | 16530    | 16342  |  -188   |
| list           | 10928    | 11136  |  208    |
| _lru_list_elem | N/A      | 5609   |  5609   |

快速谷歌发现_lru_list_elem@functools.lru_cache制作,而distributed/utils.py又在https://pypi.python.org/pypi/orbited中调用_lru_list_elem

LRU缓存是多达10万个。

第二次尝试
根据代码显示为Dask应该爬升到大约10k Article

再次运行我的脚本并观察记忆后,它快速爬升直到接近100k _lru_list_elem,之后它几乎完全停止攀爬。

这似乎是这种情况,因为它在100k之后几乎是平线

key_split

所以没有泄漏,但有趣的是在Dask源代码和Python内存分析器上弄脏了

答案 1 :(得分:0)

出于诊断,日志记录和性能方面的原因,Dask调度程序会记录与固定大小deques中的工作者和客户端的许多交互。这些记录确实累积,但仅在有限的范围内。

我们还努力确保我们不会留下任何太大的东西。

看到记忆的使用率上升,直到你所看到的一个漂亮的回合数,然后保持稳定似乎与此一致。