Как очистить память для долго выполняющейся задачи rake, чтобы предотвратить превышение квоты памяти Heroku?

У меня есть задача rake, которую мне нужно запустить на Heroku в фоновом режиме как разовую задачу. Однако задачи довольно большие, и я столкнулся с «Ошибкой R14 (превышение квоты памяти)» и надеялся, что смогу получить несколько советов о том, как этого избежать.

По сути, задача просматривает таблицу «Товары» и находит товары, у которых нет изображений Product.where(images: nil). Затем задача циклически перебирает каждую запись; используя product.url, он открывает соединение с удаленным веб-сайтом (используя Nokogiri) и извлекает изображения и некоторые дополнительные данные. Размер изображений изменяется с помощью mini_magick и сохраняется в корзину S3 с помощью несущей волны.

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

Я понимаю, почему это довольно интенсивная задача памяти, но мне было интересно, может ли кто-нибудь указать мне правильное направление относительно того, как я могу очистить память после обработки и сохранения каждой записи (или даже после каждых 100 записей) .

В качестве альтернативы/дополнительно есть ли способ автоматического перезапуска задачи Heroku после ее автоматического завершения?


person 8bithero    schedule 30.09.2017    source источник


Ответы (1)


Если вы перебираете каждую запись, вы можете заставить GC запуститься:

Products.where(images: nil).each_with_index do |image, index|
  if index % 100 == 0
    GC.start
  end
end
person Graham Slick    schedule 30.09.2017
comment
Ага! Похоже, я делаю шаг в правильном направлении. Спасибо! Таким образом, в основном это будет запускать сборку мусора каждые 100 записей? Можно ли это также сделать, используя in_batches вместо each_with_index. Возможно, это немного выходит за рамки, но есть ли у вас какие-либо советы по поиску оптимального количества или записей перед сборкой мусора? (например, статьи, драгоценные камни и т. д.) - person 8bithero; 30.09.2017
comment
Никогда не пробовал с in_batches, но не понимаю, почему это не должно работать :-) Чтобы найти оптимальное количество записей, я бы распечатал GC.stats для разных размеров пакетов и посмотрел вывод. Нашел эту статью, объясняющую GC.stats speedshop.co /2017/03/09/a-guide-to-gc-stat.html - person Graham Slick; 30.09.2017