Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I prevent my Rails query from maxing out memory

I'm sshing into a server running my Rails app in order to run queries. Despite using find_each, the server's memory is getting eaten up by my console session and I'm not sure why. Based on this SO answer, I'm also using ActiveRecord::Base.uncached to prevent ActiveRecord from caching all the objects and eating up memory.

Edit: Figured it out, thanks to @user2864740 and Micah Fivecoate. The issue was with sending off tasks to Resque, which I'm doing with the Resque Delayable gem (See answer below).

Here's what I'm doing:

ssh cron.ec2.company-name.com
cd /var/www/company-name.com/current; bundle exec rails console production

Then, in the console:

ActiveRecord::Base.uncached do
  ModelObject.find_each do |obj|
    a = AnotherModelObject.find_by_model_id(obj.id)
    a ||= AnotherModelObject.create!(obj.id)
    a.send_task_to_resque
  end
end

As soon as I kill my SSH session, the memory is freed up.

I'm running Rails 3.2.15 with ruby 1.9.3p327 on Linux.

I'm getting the text of all the SQL queries sent back to me over the SSH session—maybe this is kept in memory or something? Next I might try with conf.echo = false and ActiveRecord::Base.logger.level = 1. Edit: This didn't fix the memory usage

like image 840
MaxGabriel Avatar asked Dec 06 '13 02:12

MaxGabriel


1 Answers

The issue was with sending tasks to Resque. Thanks to @user2864740 for having this idea.

First I tested by using an empty find_each block, and that didn't cause memory growth. Then I tried a find_each block that created an ActiveRecord object, and that didn't cause memory growth.

Finally I tested doing a find_each over records and sending off a task to resque. This alone caused the memory to steadily climb and not fall. I should have also mentioned that I'm using the ResqueDelayable gem to dispatch tasks to resque, and it might be implicated by this.

like image 82
MaxGabriel Avatar answered Nov 03 '22 05:11

MaxGabriel