Я делаю предисловие к тому факту, что я относительный новичок в Java / Scala, поэтому я не исключаю, что есть нечто очевидное, чего я не делаю.
У меня есть приложение Scala, которое через Hibernate подключается к базе данных MySQL. Приложение предназначено для обработки большого объема данных, около 2 750 000 записей, поэтому я постарался максимально оптимизировать его.
Он работает на моей рабочей станции, представляющей собой QuadCore Intel Xeon с 6 ГБ ОЗУ (1033 МГц), и работает хорошо и быстро для первых 70 тыс. Записей, завершая их примерно за 15 минут. К тому времени, он достиг 90 КБ, это заняло около 25 минут, поэтому что-то замедляет его до ползания.
Я проверил таймеры кода Hibernate, и поиск в базе данных занимает столько же времени, как обычно. Я даже пытался заставить ручной сборщик мусора попытаться сделать это, но это тоже не работает.
Код выглядит примерно так:
val recordCount = repo.recordCount
val batchSize = 100
val batches = (0 to recordCount by batchSize).toList
val batchJobs = {
for (batchStart <- batches) yield {
future(new RecordFormatter().formatRecords(new Repo(sessionFactory.openSession),batchStart,batchSize)
}
awaitAll(100000,batchJobs: *_)
Внутри RecordFormatter (который на самом деле не назван так, если вы удивляетесь моей безумной схеме именования), он выполняет запрос для следующих 100 записей, а затем другой запрос, чтобы получить обратно фактические записи (используя между конечные значения) затем записывает их в текстовый файл как CSV. Если посмотреть на вывод таймера, каждая операция в форматере записи занимает около 5 секунд, чтобы извлечь записи, а затем 0,1 секунды, чтобы вывести их в файл.
Несмотря на это, после замедления он обрабатывает только около 12 пакетов по 100 записей в минуту, а не 40 пакетов по 100 записей в минуту при первом запуске процесса.
Он регулярно очищает сессию и закрывает ее в конце каждого запуска RecordFormatter (каждый RecordFormatter имеет свой собственный сеанс).
В основном я ищу какие-то известные ошибки со Scala и Futures. Я заметил, что когда он замедляется, он, кажется, не использует все восемь возможных потоков, которые, безусловно, могли бы объяснить падение скорости, но для меня загадка, почему он внезапно останавливается и всегда находится около отметки 75k.
Спасибо!
РЕДАКТИРОВАТЬ: обновленный код, чтобы показать, что он использует yield и awaitAll в случае, если это имеет значение.