Я столкнулся с проблемой оптимизации. Я нахожусь в середине написания службы на основе Scala, которая использует Play Framework и ElasticSearch для анализа около 200 тыс. Документов в индексе.Scala: Проблемы с памятью
Теперь анализ может быть выполнен только на всех документах, и у меня есть класс модели поверх ES, который при передаче в виде списка другому методу рисует анализ класса модели.
Теперь, чтобы получить документы 200k сразу и проанализировать их, не может быть и речи, поскольку это выходит за рамки наших ограничений. Так что я сделал это - Изнутри рекурсивной функции:
def getOverallAnalytics(accumulatedAnalytics: Map[...], limit: Int, startFrom: Int) = {
ElasticModel.getAnalytics(limit, startFrom).flatMap({
case (hasMore, newAnalytics) => {
val combinedAnalytics = combine(accumulatedAnalytics, newAnalytics)
if (hasMore) getOverallAnalytics(combinedAnalytics, limit, startFrom + limit)
else Future(newAccumulator)
}
})
}
И у вас есть;
object ElasticModel {
getAnalytics(limit, startFrom) = {
val recordObjects = queryElastic.flatMap(result => new ElasticModel(result))
Future((haveMore(), getAnalysis(recordObjects))) //
}
}
Что-то на этот счет. Теперь на карте, содержащей аналитику, имеется очень маленький набор ключей. Учитывая это, нельзя ожидать, что a
java.lang.OutOfMemoryError:
Unable to create new native thread
Это работает на 16 ГБ оперативной памяти.
Мои предположения: recordObjects
не продолжает потреблять память после вызова getAnalytics
отделки.
Это похоже на единственную возможность, когда это происходит не так.
Что именно я делаю неправильно здесь?
Я думаю, что у вас меньше традиционной ошибки OOM и больше проблем с ресурсами на вашем компьютере. Является ли ваш threadpool ограниченным, и если да, то какой максимальный размер? Кроме того, у вас есть настройка вашего компьютера, чтобы иметь большое количество доступных дескрипторов файлов, так как эта ошибка может возникнуть из-за этого. Правильно ли вы закрываете свои http-соединения с ES, чтобы они не просочились? – cmbaxter