У меня есть запрос вроде:
query = HistoryLogs.query()
query = query.filter(HistoryLogs.exec_id == exec_id)
iter = query.iter()
for ent in iter:
# write log to file, nothing memory intensive
Я добавил журналы для for l oop, и чтение 10K строк увеличивает использование памяти на 200 МБ, затем чтение следующих 10K строк добавляет дополнительные 200 МБ и т. Д. , Чтение 100 КБ требует 2 ГБ, что превышает ограничение памяти верхнего уровня.
Я попытался очистить memcache в for для l oop, после чтения 10K строк, добавив:
# clear ndb cache in order to reduce memory footprint
context = ndb.get_context()
context.clear_cache()
в для l oop на каждой 10K-й итерации, но это приводило к тайм-ауту запроса, возникала ошибка BadRequestError: The requested query has expired. Please restart it with the last cursor to read more results. ndb
.
Я изначально ожидал, что при использовании query.iter()
вместо query.fetch()
Я бы не столкнулся с проблемой памяти, и память была бы почти постоянной, но это не так. Есть ли способ читать данные с помощью итератора, не превышая ни времени, ни ограничений памяти? Очистив кэш контекста, я вижу, что потребление памяти почти постоянно, но я столкнулся с проблемами со временем, необходимым для извлечения всех строк.
Кстати, есть много строк, которые можно получить, вплоть до 150К. Можно ли сделать это с помощью некоторых простых настроек или мне нужно более сложное решение, например, которое будет использовать параллелизацию?