Я читаю некоторые gzipped данные из s3, используя dask (замена SQL-запроса). Тем не менее, похоже, что есть кеширование файла данных или распакованный файл где-то, который хранится в системной памяти. NB это должно быть выполнено, тестовые данные здесь используются из набора тестов pandas в общедоступном ведре s3.
import dask.dataframe as dd
import pandas as pd
import psutil as ps
import os
#for easier vis
mb = 1048576
def mytestfunc(file):
process = ps.Process(os.getpid())
print('initial memory: {0}'.format(process.memory_info().rss/mb))
data = dd.read_csv(file, compression = 'gzip', blocksize = None, storage_options = {'anon':True})
print('dask plan memory: {0}'.format(process.memory_info().rss/mb))
data = data.compute()
print('data in memory: {0}'.format(process.memory_info().rss/mb))
print('data frame usage: {0}'.format(data.memory_usage(deep=True).sum()/mb))
return data
process = ps.Process(os.getpid())
print('before function call: {0}'.format(process.memory_info().rss/mb))
out = mytestfunc('s3://pandas-test/large_random.csv.gz')
print('After function call: {0}'.format(process.memory_info().rss/mb))
# out = mytestfunc('s3://pandas-test/tips.csv.gz')
# print('After smaller function call: {0}'.format(process.memory_info().rss/mb))
Что дает мне:
before function call: 76.984375
initial memory: 76.984375
dask plan memory: 92.9921875
data in memory: 224.71484375
data frame usage: 38.14704895019531
After function call: 224.7265625
Наивно, я ожидаю, что вызов "после функции" будет "перед вызовом функции", а также фрейм данных и немного накладных расходов. Здесь gzip равен 43 Мбайт, и в моем реальном примере накладные расходы составляют около 90 мб, эта дополнительная часть составляет около 50 гб дополнительной памяти для 10-гигабайтного фрейма.
Вы можете видеть, что память освобождается, если вы повторно запускаете другой файл меньшего размера - раскомментируйте повтор в меньшем файле, чтобы увидеть его. Это также показывает, что увеличение связано с размером файла - вы можете переключить порядок и сначала запустить "подсказки", а память останется на ~ 90 мб.
Я предполагаю, что dask, s3fs или pandas где-то держит файл или расстегнутое содержимое в буфере, но я не смог его отслеживать, чтобы очистить его.
Любые идеи о том, как уменьшить использование этой памяти или освободить буфер?
EDIT: пример вышеупомянутого вывода для некоторых моих реальных данных - 32 gzipped файлов:
before function call: 70.69921875
initial memory: 70.69921875
dask plan memory: 80.16015625
data in memory: 33991.69921875
data frame usage: 10824.553115844727
After function call: 33991.69921875
Я понимаю, что у dask будет более высокое использование пиковой памяти, чем цикл pandas над теми же 32 файлами, но я до сих пор не понимаю, почему он не освобождается.