0

У нас есть приложение App Engine, которое записывает много файлов относительно большого размера в Google Cloud Store. Эти файлы представляют собой CSV-файлы, которые динамически создаются, поэтому мы используем Python StringIO.StringIO в качестве буфера и csv.writer в качестве интерфейса для записи в этот буфер.App Engine Отложенные: отслеживание утечек памяти

В общем, наш процесс выглядит следующим образом:

# imports as needed 
# (gcs is the Google Cloud Store client) 

buffer = StringIO.StringIO() 
writer = csv.writer(buffer) 

# ... 
# write some rows 
# ... 

data = file_buffer.getdata() 
filename = 'someFilename.csv' 

try: 
    with gcs.open(filename, content_type='text/csv', mode='w') as file_stream: 
     file_stream.write(data) 
     file_stream.close() 

except Exception, e: 
    # handle exception 
finally: 
    file_buffer.close() 

Как мы понимаем, csv.writer не нужно закрывать себя. Скорее всего, необходимо закрыть только buffer и file_stream.


Бежит вышеописанный процесс в deferred, вызываемые очередями задач App Engine. В конечном счете, мы получим следующее сообщение об ошибке после нескольких вызовов нашей задачи:

Превышен мягкий частный предел памяти объемом 128 Мб с 142 МБ после обслуживания 11 запросов всего

Очевидно, то существует утечка памяти в нашем приложении. Однако, если приведенный выше код верен (что мы допускаем, может быть, и не так), то наша единственная идея заключается в том, что через обслуживание наших запросов проходит некоторое количество памяти (как указывает сообщение об ошибке).

Таким образом, нам интересно, поддерживаются ли некоторые объекты App Engine во время выполнения deferred. Следует также отметить, что наши CSV в конечном итоге успешно записаны, несмотря на эти сообщения об ошибках.

+1

' "Очевидно, то, есть утечка памяти"' - не обязательно.Использование базовой памяти приложения (со всем загруженным кодом) может быть выше, чем при запуске. 128M не так много, по умолчанию для бэкэнд-экземпляров в настоящее время B2/256M. Также важны пики параллельных обработанных запросов. Также см. Http://stackoverflow.com/questions/32981118/how-does-app-engine-python-manage-memory-across-requests-exceeded-soft-privat, http://stackoverflow.com/questions/31853703/ google-app-engine-db-query-memory-usage, http://stackoverflow.com/questions/33036334/memory-leak-in-google-ndb-library –

+0

Я думаю, что это могло бы стать ответом! Очень интересно, как экземпляр B2 в Google имеет половину памяти ... – nmagerko

+0

как вы используете отложенные задачи? по одному или кучу много из них? Связаны ли их казни? –

ответ

0

Описанный симптом не обязательно указание на утечку памяти приложения. Потенциальные альтернативные объяснения включают:

  • базовый объем памяти на приложения (которое для скриптового языка песочницах, как питон может быть больше, чем след в момент запуска экземпляра, см Memory usage differs greatly (and strangely) between frontend and backend) может оказаться слишком высокой для instance class сконфигурированный для приложение/модуль. Исправить - chose a higher memory instance class (что в качестве побочного эффекта также означает более быстрый экземпляр класса). В качестве альтернативы, если скорость убийства экземпляра из-за превышения пределов памяти допустима, просто позвольте GAE перерабатывать экземпляры :)
  • пики активности, особенно если включена обработка многопоточных запросов, означает более высокое потребление памяти, а также потенциальную перегрузку сборщик мусора памяти. Ограничение количества запросов, выполняемых параллельно, добавление (более высоких) задержек в обработке отложенных задач с более низким приоритетом и другие подобные меры, уменьшающие среднюю скорость обработки запросов на один экземпляр, могут помочь сборщику мусора получить возможность очистить остатки от запросов. Масштабируемость не должна быть повреждена (с dynamic scaling), так как другие случаи будут начаты, чтобы помочь с пиком активности.

Похожие Q & Как:

Смежные вопросы