Hi mongrel-users, This is my first post, so I''m not sure if it''s been asked before, but I can''t find an answer anywhere. If I have one rails application running, one processor I''m running it on, and mongrel is multi-threaded, why should I have more than one mongrel running? Everyone seems to agree on 3-5 mongrels per rails app, but why? I must be missing something, sorry if it''s obvious. TIA --hax
On 22.8.2006, at 18.47, hax wrote:> Hi mongrel-users, > > This is my first post, so I''m not sure if it''s been asked before, but > I can''t find an answer anywhere. > > If I have one rails application running, one processor I''m running it > on, and mongrel is multi-threaded, why should I have more than one > mongrel running? > > Everyone seems to agree on 3-5 mongrels per rails app, but why?Rails is not threadsafe. http://rubyforge.org/pipermail/mongrel-users/2006-August/000930.html //jarkko -- Jarkko Laine http://jlaine.net http://odesign.fi
> This is my first post, so I''m not sure if it''s been asked before, but > I can''t find an answer anywhere. > > If I have one rails application running, one processor I''m running it > on, and mongrel is multi-threaded, why should I have more than one > mongrel running? > > Everyone seems to agree on 3-5 mongrels per rails app, but why?Performance... somewhere Zed has an article on how to benchmark things.. something along the lines of benchmark a blank static html page. That''s as fast as your server will go. Then create a simple action that renders "Hello" as text say, with one mongrel. Benchmark that. Keep increasing the number of mongrels until you don''t get any more performance improvements. For us, it was 4. -philip
> Rails is not threadsafe. > > http://rubyforge.org/pipermail/mongrel-users/2006-August/000930.html > > //jarkkoSo what happens when the mongrel gets more than one request at a time? When I run httpref against it, the mongrel process can serve up large number of rails pages before it gets bogged down. And when it does break, it says "mongrel timed out this thread: too many open files". So it must be doing some threading, even if rails isn''t threadsafe. If it was 1 request per mongrel process, 1 process shouldn''t be able to serve up very many per second. httpref tells me its prettty fast though. Thoughts? --hax
> So what happens when the mongrel gets more than one request at a time? > When I run httpref against it, the mongrel process can serve up large > number of rails pages before it gets bogged down. > And when it does break, it says "mongrel timed out this thread: too > many open files". So it must be doing some threading, even if rails > isn''t threadsafe. > If it was 1 request per mongrel process, 1 process shouldn''t be able > to serve up very many per second. httpref tells me its prettty fast > though. > > Thoughts?It will accept multiple connections but it will only feed one connection at a time through the rails handler, because as others have stated rails is not thread safe.
On 8/22/06, hax <hax at cheaphacks.info> wrote:> So what happens when the mongrel gets more than one request at a time? > When I run httpref against it, the mongrel process can serve up large > number of rails pages before it gets bogged down. > And when it does break, it says "mongrel timed out this thread: too > many open files". So it must be doing some threading, even if rails > isn''t threadsafe. > If it was 1 request per mongrel process, 1 process shouldn''t be able > to serve up very many per second. httpref tells me its prettty fast > though.Take a look at the Rails handler. It''s pretty easy code to read. There is a guard mutex that makes sure that the Rails handler only processes a single request through Rails at a time. So, Mongrel receives your requests and Mongrel multithreads them, but the Rails handler only eats them one at a time. If Rails could safely multithread, then the guard mutex and it''s synchronization (which you can turn off already if you really want to) wouldn''t be required, and overall performance on a single Mongrel, for Rails, should be better. Kirk Haines
>> >> http://rubyforge.org/pipermail/mongrel-users/2006-August/000930.html >> >> //jarkko > > So what happens when the mongrel gets more than one request at a time? > When I run httpref against it, the mongrel process can serve up large > number of rails pages before it gets bogged down. > And when it does break, it says "mongrel timed out this thread: too > many open files". So it must be doing some threading, even if rails > isn''t threadsafe. > If it was 1 request per mongrel process, 1 process shouldn''t be able > to serve up very many per second. httpref tells me its prettty fast > though.Search the lists... I don''t remember the exact details but basically mongrel is threaded... right up till it hands the request off to rails, then it locks, does the rails request, gets the response, and goes back into threaded mode. So technically you can''t process more than 1 rails request at a time, but since many requests are way under a second you get the appearance that you can. Or something like that :)
Hi I''ll have a shot ;)> If I have one rails application running, one processor I''m running it > on, and mongrel is multi-threaded, why should I have more than one > mongrel running?Mongrel might be internally multi threaded, but it only serves one request at any given moment. So all your web users will have to be serialized through this rather small .. tube. By setting up load balancing via pound to a few mongrels, you can take better advantage of your CPU, running things in parallel. Large-scale rails applications are deployed this way, mostly on more than one machine even to distribute the load across many CPU''s and disks. Hope that explains... kaspar neotrivium.com - the swiss ruby shop
On Tue, 2006-08-22 at 11:31 -0500, Philip Hallstrom wrote:> > This is my first post, so I''m not sure if it''s been asked before, but > > I can''t find an answer anywhere. > > > > If I have one rails application running, one processor I''m running it > > on, and mongrel is multi-threaded, why should I have more than one > > mongrel running? > > > > Everyone seems to agree on 3-5 mongrels per rails app, but why? > > Performance... somewhere Zed has an article on how to benchmark things.. > something along the lines of benchmark a blank static html page. That''s > as fast as your server will go. Then create a simple action that renders > "Hello" as text say, with one mongrel. Benchmark that. Keep increasing > the number of mongrels until you don''t get any more performance > improvements. > > For us, it was 4.Wow, someone listened. Nice job Philip. -- Zed A. Shaw http://www.zedshaw.com/ http://mongrel.rubyforge.org/ http://www.lingr.com/room/3yXhqKbfPy8 -- Come get help.
On Tue, 2006-08-22 at 11:47 -0400, hax wrote:> Hi mongrel-users, > > This is my first post, so I''m not sure if it''s been asked before, but > I can''t find an answer anywhere. > > If I have one rails application running, one processor I''m running it > on, and mongrel is multi-threaded, why should I have more than one > mongrel running? > > Everyone seems to agree on 3-5 mongrels per rails app, but why? > > I must be missing something, sorry if it''s obvious.You''ve got three things you''re dealing with when you do this: 1) Ruby uses a select() function to make it seem like it has threads. This is called "green threads" in the Java world. When you put about 2-4 mongrels per CPU on your machine, you get a slightly better utilization. 2) Rails isn''t thread safe (as lots of people have said) so requests come in to mongrel, get threaded up, and then queued behind Rails. Once Rails is done then threads send the response out. If you have a small site and most of your rails actions are quick then don''t worry about it. If you need more concurrency then you have to use more processes. 3) Because ruby uses select() it has a OS kernel level limit for the number of files it can handle. Usually that''s 1024 but it can be 256 on some systems. If you have one mongrel process then you''ll really quickly run out of these when serving files, doing fragment/action caching, etc. You have to add more processes to be able to handle more open files concurrently. That''s the why. If you''re site is small then just do one. It''s easier. Then slowly expand it out and get more "hardcore" as you need it. -- Zed A. Shaw http://www.zedshaw.com/ http://mongrel.rubyforge.org/ http://www.lingr.com/room/3yXhqKbfPy8 -- Come get help.
On Tue, 2006-08-22 at 15:11 -0400, hax wrote:> > Rails is not threadsafe. > > > > http://rubyforge.org/pipermail/mongrel-users/2006-August/000930.html > > > > //jarkko > > So what happens when the mongrel gets more than one request at a time? > When I run httpref against it, the mongrel process can serve up large > number of rails pages before it gets bogged down. > And when it does break, it says "mongrel timed out this thread: too > many open files". So it must be doing some threading, even if rails > isn''t threadsafe. > If it was 1 request per mongrel process, 1 process shouldn''t be able > to serve up very many per second. httpref tells me its prettty fast > though.You actually can find out for yourself right now. I have the latest pre-release up with a new debugging feature just for folks like you. First, install the pre-release like this: sudo gem install mongrel --source=http://mongrel.rubyforge.org/releases/ Then run your application in production mode like normal. Right after it starts up, do this: killall -USR1 mongrel_rails Go look at the log/mongrel.log and you''ll see that it says it set $mongrel_debug_client to true. The USR1 signal toggles this "client debugging" true/false. When it''s true Mongrel will print out log messages that help you debug client interactions: * BAD CLIENT is only logged now when USR1 is on. * Full request data is printed out when there''s an HTTP parsing error so you can see what the problem is. * It will print the number of threads waiting for rails on 10 second intervals. * It prints stack traces for exceptions found (I''m expanding this more). It''s also very light, so you could enable it all the time if you want. Now, what you want to do is hit your app with httperf like this: httperf --server 127.0.0.1 --port 3000 --uri /some/rails/uri --num-conns 1000 --rate 100 And then watch your mongrel.log print out the request counts as they pile up behind rails and then move out. Play with num-conns and rate until you can choke mongrel, find the sweet spot, etc. Have fun and let me know if you find bugs. -- Zed A. Shaw http://www.zedshaw.com/ http://mongrel.rubyforge.org/ http://www.lingr.com/room/3yXhqKbfPy8 -- Come get help.
> > You actually can find out for yourself right now. I have the latest > pre-release up with a new debugging feature just for folks like you. > > First, install the pre-release like this: > > sudo gem install mongrel > --source=http://mongrel.rubyforge.org/releases/ > > Then run your application in production mode like normal. Right after > it starts up, do this: > > killall -USR1 mongrel_rails > > Go look at the log/mongrel.log and you''ll see that it says it set > $mongrel_debug_client to true. The USR1 signal toggles this "client > debugging" true/false. When it''s true Mongrel will print out log > messages that help you debug client interactions: > > * BAD CLIENT is only logged now when USR1 is on. > * Full request data is printed out when there''s an HTTP parsing > error so > you can see what the problem is. > * It will print the number of threads waiting for rails on 10 second > intervals. > * It prints stack traces for exceptions found (I''m expanding this > more). > > It''s also very light, so you could enable it all the time if you want. > > Now, what you want to do is hit your app with httperf like this: > > httperf --server 127.0.0.1 --port 3000 --uri /some/rails/uri --num- > conns > 1000 --rate 100 > > And then watch your mongrel.log print out the request counts as they > pile up behind rails and then move out. Play with num-conns and rate > until you can choke mongrel, find the sweet spot, etc. > > Have fun and let me know if you find bugs.Wow, amazing responses, that answers every question I could have possibly had plus more :) Thanks everyone! Also, Zed, you rock :) --hax