Ошибка Heroku R14 (превышена квота памяти): Как это решить?
У меня есть приложение Rails 3.1 на Heroku. Я вижу много таких ошибок:
Ошибка R14 (превышена квота памяти)
Обычно предыдущая запись в журнале показывает:
Работающий процесс mem = 522M (102.1%)
Это немного меняется, но никогда не бывает много и может произойти после почти любого запроса URL-адреса, поэтому он не имеет отношения к определенному действию контроллера, насколько я могу судить.
Это классический блок записей журнала:
2012-01-16T02:35:57+00:00 heroku[router]: PUT prizequiz.herokuapp.com/mobile_users/1 dyno=web.1 queue=0 wait=0ms service=55ms status=401 bytes=27
2012-01-16T02:35:58+00:00 heroku[router]: PUT prizequiz.herokuapp.com/mobile_users/1 dyno=web.1 queue=0 wait=0ms service=155ms status=200 bytes=1
2012-01-16T02:36:02+00:00 heroku[router]: PUT prizequiz.herokuapp.com/mobile_users/1 dyno=web.1 queue=0 wait=0ms service=13ms status=401 bytes=27
2012-01-16T02:36:02+00:00 heroku[router]: PUT prizequiz.herokuapp.com/mobile_users/1 dyno=web.1 queue=0 wait=0ms service=147ms status=200 bytes=1
2012-01-16T02:36:09+00:00 heroku[router]: POST prizequiz.herokuapp.com/mobile_users dyno=web.1 queue=0 wait=0ms service=87ms status=201 bytes=624
2012-01-16T02:36:11+00:00 heroku[router]: GET prizequiz.herokuapp.com/quizzes/1/questions dyno=web.1 queue=0 wait=0ms service=5ms status=401 bytes=27
2012-01-16T02:36:11+00:00 heroku[router]: GET prizequiz.herokuapp.com/quizzes/1/questions dyno=web.1 queue=0 wait=0ms service=290ms status=200 bytes=81412
2012-01-16T02:36:15+00:00 heroku[router]: PUT prizequiz.herokuapp.com/mobile_users/1 dyno=web.1 queue=0 wait=0ms service=10ms status=401 bytes=27
2012-01-16T02:36:16+00:00 heroku[router]: PUT prizequiz.herokuapp.com/mobile_users/1 dyno=web.1 queue=0 wait=0ms service=67ms status=200 bytes=1
2012-01-16T02:36:33+00:00 heroku[router]: POST prizequiz.herokuapp.com/quizzes/1/scores dyno=web.1 queue=0 wait=0ms service=10ms status=401 bytes=27
2012-01-16T02:36:33+00:00 heroku[router]: POST prizequiz.herokuapp.com/quizzes/1/scores dyno=web.1 queue=0 wait=0ms service=132ms status=201 bytes=230
2012-01-16T02:36:55+00:00 heroku[web.1]: Process running mem=522M(102.1%)
2012-01-16T02:36:55+00:00 heroku[web.1]: Error R14 (Memory quota exceeded)
2012-01-16T02:37:17+00:00 app[web.1]:
2012-01-16T02:37:17+00:00 app[web.1]:
2012-01-16T02:37:17+00:00 app[web.1]: Started POST "/quizzes/1/scores" for 177.53.80.25 at 2012-01-16 02:37:17 +0000
2012-01-16T02:37:17+00:00 app[web.1]: cache: [POST /quizzes/1/scores] invalidate, pass
2012-01-16T02:37:17+00:00 app[web.1]:
2012-01-16T02:37:17+00:00 app[web.1]:
2012-01-16T02:37:17+00:00 app[web.1]: Started POST "/quizzes/1/scores" for 177.53.80.25 at 2012-01-16 02:37:17 +0000
2012-01-16T02:37:17+00:00 app[web.1]: cache: [POST /quizzes/1/scores] invalidate, pass
2012-01-16T02:37:17+00:00 heroku[router]: POST prizequiz.herokuapp.com/quizzes/1/scores dyno=web.1 queue=0 wait=0ms service=44ms status=201 bytes=230
2012-01-16T02:37:17+00:00 heroku[web.1]: Process running mem=522M(102.1%)
2012-01-16T02:37:17+00:00 heroku[web.1]: Error R14 (Memory quota exceeded)
2012-01-16T02:37:17+00:00 heroku[router]: POST prizequiz.herokuapp.com/quizzes/1/scores dyno=web.1 queue=0 wait=0ms service=16ms status=401 bytes=27
2012-01-16T02:37:20+00:00 app[web.1]:
2012-01-16T02:37:20+00:00 app[web.1]:
2012-01-16T02:37:20+00:00 app[web.1]: Started GET "/quizzes/1/scores/current_game" for 177.53.80.25 at 2012-01-16 02:37:20 +0000
2012-01-16T02:37:20+00:00 app[web.1]: cache: [GET /quizzes/1/scores/current_game] miss
2012-01-16T02:37:20+00:00 app[web.1]:
2012-01-16T02:37:20+00:00 app[web.1]:
2012-01-16T02:37:20+00:00 app[web.1]: Started GET "/quizzes/1/scores/current_game" for 177.53.80.25 at 2012-01-16 02:37:20 +0000
2012-01-16T02:37:20+00:00 heroku[router]: GET prizequiz.herokuapp.com/quizzes/1/scores/current_game dyno=web.1 queue=0 wait=0ms service=8ms status=401 bytes=27
2012-01-16T02:37:20+00:00 app[web.1]: cache: [GET /quizzes/1/scores/current_game] miss
2012-01-16T02:37:20+00:00 heroku[router]: GET prizequiz.herokuapp.com/quizzes/1/scores/current_game dyno=web.1 queue=0 wait=0ms service=6ms status=401 bytes=27
2012-01-16T02:37:20+00:00 app[web.1]:
2012-01-16T02:37:20+00:00 app[web.1]:
2012-01-16T02:37:20+00:00 app[web.1]: Started POST "/quizzes/1/scores" for 177.53.80.25 at 2012-01-16 02:37:20 +0000
2012-01-16T02:37:20+00:00 heroku[router]: POST prizequiz.herokuapp.com/quizzes/1/scores dyno=web.1 queue=0 wait=0ms service=33ms status=401 bytes=27
2012-01-16T02:37:20+00:00 app[web.1]: cache: [POST /quizzes/1/scores] invalidate, pass
2012-01-16T02:37:20+00:00 app[web.1]:
2012-01-16T02:37:20+00:00 app[web.1]:
2012-01-16T02:37:20+00:00 app[web.1]: Started GET "/quizzes/1/scores/current_game" for 177.53.80.25 at 2012-01-16 02:37:20 +0000
2012-01-16T02:37:20+00:00 app[web.1]:
2012-01-16T02:37:20+00:00 app[web.1]:
У меня установлен New Relic, но не удалось идентифицировать что-либо в использовании.
Будем рады предоставить дополнительную информацию, если это необходимо. У меня также есть выдающийся запрос поддержки на Heroku для этого, но пока (2 дня, отмеченные как срочные) у меня не было ответа.
Добавление веб-динамиков не имеет значения.
ОБНОВЛЕНИЕ, я добавил драгоценный камень oink, и это образец результата
2012-01-26T08:24:25+00:00 app[web.1]:
2012-01-26T08:24:25+00:00 app[web.1]:
2012-01-26T08:24:25+00:00 app[web.1]: Started PUT "/mobile_users/1" for 110.49.234.219 at 2012-01-26 08:24:25 +0000
2012-01-26T08:24:26+00:00 app[web.1]: Oink Action: mobile_users#update
2012-01-26T08:24:26+00:00 app[web.1]: Memory usage: 286276 | PID: 16
2012-01-26T08:24:26+00:00 app[web.1]: Instantiation Breakdown: Total: 2 | MobileUser: 2
2012-01-26T08:24:26+00:00 app[web.1]: Oink Log Entry Complete
2012-01-26T08:24:26+00:00 app[web.1]: cache: [PUT /mobile_users/1] invalidate, pass
2012-01-26T08:24:26+00:00 heroku[router]: PUT prizequiz.herokuapp.com/mobile_users/1 dyno=web.1 queue=0 wait=0ms service=460ms status=200 bytes=1
2012-01-26T08:24:38+00:00 heroku[web.1]: Process running mem=537M(104.9%)
2012-01-26T08:24:38+00:00 heroku[web.1]: Error R14 (Memory quota exceeded)
2012-01-26T08:24:43+00:00 app[web.1]:
2012-01-26T08:24:43+00:00 app[web.1]:
2012-01-26T08:24:43+00:00 app[web.1]: Started PUT "/mobile_users/1" for 103.1.165.23 at 2012-01-26 08:24:43 +0000
2012-01-26T08:24:43+00:00 heroku[router]: PUT prizequiz.herokuapp.com/mobile_users/1 dyno=web.1 queue=0 wait=0ms service=544ms status=401 bytes=27
2012-01-26T08:24:43+00:00 app[web.1]: Oink Action: mobile_users#update
2012-01-26T08:24:43+00:00 app[web.1]: Memory usage: 288876 | PID: 19
2012-01-26T08:24:43+00:00 app[web.1]: Instantiation Breakdown: Total: 0
2012-01-26T08:24:43+00:00 app[web.1]: Oink Log Entry Complete
2012-01-26T08:24:43+00:00 app[web.1]: cache: [PUT /mobile_users/1] invalidate, pass
2012-01-26T08:24:47+00:00 app[web.1]:
2012-01-26T08:24:47+00:00 app[web.1]:
2012-01-26T08:24:47+00:00 app[web.1]: Started PUT "/mobile_users/1" for 103.1.165.23 at 2012-01-26 08:24:47 +0000
2012-01-26T08:24:48+00:00 app[web.1]: Oink Action: mobile_users#update
2012-01-26T08:24:48+00:00 app[web.1]: Memory usage: 286412 | PID: 16
2012-01-26T08:24:48+00:00 app[web.1]: Instantiation Breakdown: Total: 2 | MobileUser: 2
2012-01-26T08:24:48+00:00 app[web.1]: Oink Log Entry Complete
2012-01-26T08:24:48+00:00 heroku[router]: PUT prizequiz.herokuapp.com/mobile_users/1 dyno=web.1 queue=0 wait=0ms service=432ms status=200 bytes=1
2012-01-26T08:24:48+00:00 app[web.1]: cache: [PUT /mobile_users/1] invalidate, pass
2012-01-26T08:24:59+00:00 heroku[web.1]: Process running mem=537M(104.9%)
2012-01-26T08:24:59+00:00 heroku[web.1]: Error R14 (Memory quota exceeded)
2012-01-26T08:25:20+00:00 heroku[web.1]: Process running mem=537M(104.9%)
2012-01-26T08:25:20+00:00 heroku[web.1]: Error R14 (Memory quota exceeded)
2012-01-26T08:25:41+00:00 heroku[web.1]: Process running mem=537M(104.9%)
2012-01-26T08:25:41+00:00 heroku[web.1]: Error R14 (Memory quota exceeded)
2012-01-26T08:26:32+00:00 heroku[router]: PUT prizequiz.herokuapp.com/mobile_users/1 dyno=web.1 queue=0 wait=0ms service=34ms status=401 bytes=27
2012-01-26T08:27:04+00:00 app[web.1]:
2012-01-26T08:27:04+00:00 app[web.1]:
2012-01-26T08:27:04+00:00 app[web.1]: Started PUT "/mobile_users/1" for 103.1.165.23 at 2012-01-26 08:27:04 +0000
2012-01-26T08:27:04+00:00 app[web.1]: Oink Action: mobile_users#update
2012-01-26T08:27:04+00:00 app[web.1]: Memory usage: 288876 | PID: 19
2012-01-26T08:27:04+00:00 app[web.1]: Instantiation Breakdown: Total: 2 | MobileUser: 2
2012-01-26T08:27:04+00:00 app[web.1]: Oink Log Entry Complete
2012-01-26T08:27:04+00:00 app[web.1]: cache: [PUT /mobile_users/1] invalidate, pass
2012-01-26T08:27:04+00:00 heroku[router]: PUT prizequiz.herokuapp.com/mobile_users/1 dyno=web.1 queue=0 wait=0ms service=337ms status=200 bytes=1
2012-01-26T08:27:05+00:00 heroku[web.1]: Process running mem=537M(104.9%)
2012-01-26T08:27:05+00:00 heroku[web.1]: Error R14 (Memory quota exceeded)
2012-01-26T08:27:26+00:00 heroku[web.1]: Process running mem=537M(104.9%)
2012-01-26T08:27:26+00:00 heroku[web.1]: Error R14 (Memory quota exceeded)
2012-01-26T08:27:48+00:00 heroku[web.1]: Process running mem=537M(104.9%)
2012-01-26T08:27:48+00:00 heroku[web.1]: Error R14 (Memory quota exceeded)
2012-01-26T08:28:08+00:00 heroku[web.1]: Process running mem=537M(105.0%)
2012-01-26T08:28:08+00:00 heroku[web.1]: Error R14 (Memory quota exceeded)
2012-01-26T08:28:29+00:00 heroku[web.1]: Process running mem=537M(105.0%)
2012-01-26T08:28:29+00:00 heroku[web.1]: Error R14 (Memory quota exceeded)
2012-01-26T08:28:51+00:00 heroku[web.1]: Process running mem=537M(105.0%)
2012-01-26T08:28:51+00:00 heroku[web.1]: Error R14 (Memory quota exceeded)
2012-01-26T08:29:08+00:00 app[web.1]:
2012-01-26T08:29:08+00:00 app[web.1]:
2012-01-26T08:29:08+00:00 app[web.1]: Started PUT "/mobile_users/1" for 85.26.234.218 at 2012-01-26 08:29:08 +0000
2012-01-26T08:29:08+00:00 app[web.1]: Oink Action: mobile_users#update
2012-01-26T08:29:08+00:00 app[web.1]: Memory usage: 382404 | PID: 13
2012-01-26T08:29:08+00:00 app[web.1]: Instantiation Breakdown: Total: 0
2012-01-26T08:29:08+00:00 app[web.1]: Oink Log Entry Complete
2012-01-26T08:29:08+00:00 app[web.1]: cache: [PUT /mobile_users/1] invalidate, pass
2012-01-26T08:29:08+00:00 heroku[router]: PUT prizequiz.herokuapp.com/mobile_users/1 dyno=web.1 queue=0 wait=0ms service=86ms status=401 bytes=27
2012-01-26T08:29:09+00:00 app[web.1]:
2012-01-26T08:29:09+00:00 app[web.1]:
2012-01-26T08:29:09+00:00 app[web.1]: Started PUT "/mobile_users/1" for 85.26.234.218 at 2012-01-26 08:29:09 +0000
2012-01-26T08:29:09+00:00 app[web.1]: Oink Action: mobile_users#update
2012-01-26T08:29:09+00:00 app[web.1]: Memory usage: 382404 | PID: 13
2012-01-26T08:29:09+00:00 app[web.1]: Instantiation Breakdown: Total: 2 | MobileUser: 2
2012-01-26T08:29:09+00:00 app[web.1]: Oink Log Entry Complete
2012-01-26T08:29:09+00:00 app[web.1]: cache: [PUT /mobile_users/1] invalidate, pass
2012-01-26T08:29:09+00:00 heroku[router]: PUT prizequiz.herokuapp.com/mobile_users/1 dyno=web.1 queue=0 wait=0ms service=160ms status=200 bytes=1
2012-01-26T08:29:11+00:00 app[web.1]:
2012-01-26T08:29:11+00:00 app[web.1]:
2012-01-26T08:29:11+00:00 app[web.1]: Started PUT "/mobile_users/1" for 85.26.234.218 at 2012-01-26 08:29:11 +0000
2012-01-26T08:29:11+00:00 heroku[router]: PUT prizequiz.herokuapp.com/mobile_users/1 dyno=web.1 queue=0 wait=0ms service=101ms status=401 bytes=27
2012-01-26T08:29:11+00:00 app[web.1]: Oink Action: mobile_users#update
2012-01-26T08:29:11+00:00 app[web.1]: Memory usage: 382404 | PID: 13
2012-01-26T08:29:11+00:00 app[web.1]: Instantiation Breakdown: Total: 0
2012-01-26T08:29:11+00:00 app[web.1]: Oink Log Entry Complete
2012-01-26T08:29:11+00:00 app[web.1]: cache: [PUT /mobile_users/1] invalidate, pass
2012-01-26T08:29:12+00:00 app[web.1]:
2012-01-26T08:29:12+00:00 app[web.1]:
2012-01-26T08:29:12+00:00 app[web.1]: Started PUT "/mobile_users/1" for 85.26.234.218 at 2012-01-26 08:29:12 +0000
2012-01-26T08:29:12+00:00 heroku[web.1]: Process running mem=537M(105.0%)
2012-01-26T08:29:12+00:00 heroku[web.1]: Error R14 (Memory quota exceeded)
2012-01-26T08:29:12+00:00 app[web.1]: Oink Action: mobile_users#update
2012-01-26T08:29:12+00:00 app[web.1]: Memory usage: 288876 | PID: 19
2012-01-26T08:29:12+00:00 app[web.1]: Instantiation Breakdown: Total: 2 | MobileUser: 2
2012-01-26T08:29:12+00:00 app[web.1]: Oink Log Entry Complete
2012-01-26T08:29:12+00:00 app[web.1]: cache: [PUT /mobile_users/1] invalidate, pass
2012-01-26T08:29:12+00:00 heroku[router]: PUT prizequiz.herokuapp.com/mobile_users/1 dyno=web.1 queue=0 wait=0ms service=169ms status=200 bytes=1
2012-01-26T08:29:33+00:00 heroku[web.1]: Process running mem=537M(105.0%)
2012-01-26T08:29:33+00:00 heroku[web.1]: Error R14 (Memory quota exceeded)
Я понятия не имею, что это доказывает, кроме того, что кажется, что я не использую столько памяти, сколько Хероку думает, что я
Использование памяти: 288876 vs Работающий процесс mem = 537M (105,0%)
Ответы
Ответ 1
У меня была эта проблема.. для решения с помощью find_in_batches.
Если у кого-то еще есть эта ошибка, я поставлю код здесь.
Поскольку требуется много времени для запуска, я нашел камень progress_bar, который помогает пользователю. пусть это и здесь, потому что я считаю его обязательным почти в каждом случае.
bar = ProgressBar.new( total )
Texto.find_in_batches(:batch_size => 100) do |textos|
textos.each{| texto |
...do_stuff...
}
bar.increment! textos.size
end
Индикатор выполнения:
https://github.com/paul/progress_bar/issues
Ответ 2
Найдите код с 'Model.all.each do |something|'
и замените его на Model.find_each do |something|
. Это позволит сэкономить память, загрузив куски вашей модели в память, а не всю модель сразу.
Также обратите внимание на возможности использовать in_groups_of
или :limit
для уменьшения количества объектов, которые сохраняются в памяти за один раз.
EDIT: for_each → find_each.
Ответ 3
Heroku определяет предел RAM для каждого дино в своей политике приемлемого использования.
Вы можете использовать memprof, а именно Memprof::Middleware
, чтобы узнать, что выделяет всю память в вашем приложении во время запросов. Это действительно подходит только для использования в непроизводственной среде, так как это замедлит ваше приложение.
Обычно для приложения Rails выделяется множество объектов ActiveRecord, поэтому вы можете искать места, где вы делаете Model.find(:all).select{...}
, или похожие запросы, которые вытаскивают множество записей из БД, а затем обрабатывают их в Ruby. Лучше было бы использовать where
, чтобы ограничить то, что возвращается в приложение Rails, используя SQL.
Ответ 4
Я использовал Mongoid, и в моем случае это было из "идентификационной карты", включенной в процессе без веб-запроса (так что идентификационная карта никогда не очищалась и не росла). Установка Mongoid.identity_map_enabled = false
в этом процессе решила проблему.
Ответ 5
Кроме того, это может привести к конфигурации WEB_CONCURRENCY heroku. Например, у меня есть приложение, в котором работают 2 1x dynos. Если я использую sensible_defaults (другая конфигурация heroku), по умолчанию WEB_CONCURRENCY равняется 2 (на основе моих динамиков). Это вызывает тонну ошибок R14 в моих журналах. Если отключить sensible_defaults и установить WEB_CONCURRENCY = 1... проблема исчезнет.
Если вы не устанавливаете WEB_CONCURRENCY, и вы не используете sensible_defaults, и вы следовали за сервером (Im using Puma), настроенным с помощью документов heroku... у вас, вероятно, будет строка в puma.rb, которая выглядит например:
workers Integer(ENV['WEB_CONCURRENCY'] || 3)
Если это так, то WEB_CONCURRENCY не установлен... так что это будет 3, в котором используется еще больше памяти.
В консоли:
//просмотрите существующие настройки конфигурации.
heroku config
//IF sensible_defaults включен.
heroku config: set sensible_defaults = отключен
//установить WEB_CONCURRENCY
heroku config: установите WEB_CONCURRENCY = 1
//отслеживает журналы ошибок R14.
Ответ 6
У меня была такая же проблема, и я обновился до их 2x-динамиков в качестве разрыва остановки при попытке отладки с драгоценным камнем. Изменение конфигурации для удвоения числа динамиков не сработало после heroku restart
и не делал их на 0 и резервное копирование. Выполнение git push
после добавления драгоценного камня oink заставило обновление работать, а oink не показывает то же потребление, которое первоначально показывали журналы героя.
Ответ 7
Для меня замена RMagick на MiniMagick выполнила эту работу. Оба драгоценных камня имеют одинаковые функции изменения размера и обрезки (я использую несущую волну для загрузки изображений)
-
Обновление Gemfile
Удалите gem 'rmagick'
и добавьте gem 'mini_magick'
Выполнить bundle
-
Обновить загружаемые загрузчики несущей
Заменить include CarrierWave::RMagick
с include CarrierWave::MiniMagick
-
Развернитесь на Heroku и это!
-
Наконец, у меня нет ошибок R14 после каждого запроса.