Подтвердить что ты не робот

Ошибка 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%)

4b9b3361

Ответ 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 после каждого запроса.