Mongrel does not use the full CPU power on Windows 2003 server - ruby-on-rails

I have a deployment using:
rails 2.3.2
ruby 1.8.7
mysql db
and
3 mongrel instances (windows services) with apache as load balancer
[I know it is due for upgrade...]
OS: Windows2003
We have many CPU intensive tasks and when these occur on the 4 core machine the mongrel process is able to only use a max 25% cpu power on the core the task was scheduled.
After running many tests we noticed that it is only able to use the power of a single core and therefore there is time lag in finishing tasks.
There is a suggestion to virtualize... which is difficult to do on the client server.
Has anyone got any suggestion on how the situation can be improved? Memory does reach 250MB to 1GB for this process but this not such a big issue.
Thanks in advance
Linus

The typically used Ruby versions (MRI or YARV, i.e 1.8 or 1.9) are not able to use more than one core at a time. MRI is single-threaded and just provides green threads internally. YARV uses real OS threads but has a GIL (global interpreter lock) that ensures that only one thread is running at a time.
Thus, your mongrels are unable to use more than one core each (even if you would have coded your Rails app to be threadsafe). There are alternative Ruby implementations, like JRuby or Rubinius that provide native threads without a global interpreter lock and thus allow your app to use more than one core, but you'd probably need to adapt your app a bit.
That said, even then a single request would run in a single thread and thus only use a single core. But that is something that is hard to come by without you handling your own threads (or at least fibers in 1.9) which is most probably not worth the hassle.
So generally, the recommendation is to start multiple app server processes (mongrels in your case). I personally use about 1.5 - 3 per core (depending on the app). That way, you are able to answer that many parallel requests and fully use your available CPU power shared between them.

Related

Why are multiple Ruby processes on an EC2 server causing 100% CPU utilisation?

I have a Rails application which has 100% CPU utilization most of the time.
I am not able to figure out why there is so much load on the server. I am using the Puma web server with a default configuration, and am running multiple background jobs using the sucker-punch gem. There are 7 files which are using sucker punch jobs with 5 workers:
include SuckerPunch::Job
workers 5
I ran the top -i query and found the following processes running on the server. I can see multiple Ruby commands on the server. Can someone tell me whether this is normal behavior on a server, or if something is wrong?
Some Ways to Reduce Resource Contention
Your user space load is high (~48%), so you'll probably want to reduce the number of workers in your web application, increase the number of CPUs available on your instance, move to a version of Ruby that has better concurrency and real multi-core support (e.g. Rubinius or JRuby), or some combination of these options. Depending on what your code is actually doing, you may also need to re-architect your application to offload expensive I/O from the application server.
In addition, your steal time is quite high (~41%), so your EC2 instance is probably overloaded. Simply moving your application to a less-loaded instance may free up sufficient resources to reduce application wait times.

If Node.js is single threaded, what is Rails?

If we say Node.js is single threaded and therefore there is just one thread that handles all the requests, what is Rails?
As I understand, Node.js is both the application and the server, but I am lost on what Rails would be? How does Rails handle requests in terms of threads/processes?
Rails can be single-threaded, it can be multi-threaded, it can be multi-process (where each process is single-threaded), or it can be multi-process where each process is multi-threaded.
It really all depends upon the app server you're using, and it kind of depends upon which Ruby implementation you're using. MRI Ruby supports native threads as of 1.9, but it still maintains what's known as a global interpreter lock. The GIL prevents the Ruby interpreter from running in multiple threads at a time. In most cases that's not really a big deal though, because the thing threads are helping with the most is waiting for I/O. If you're using either JRuby or Rubinius, they can actually run Ruby code in multiple threads at a time.
Check out the different app servers and what they offer in terms of concurrency features. Unicorn is a common one for deploying multi-process/single-threaded applications. Puma is a newer app server that's capable of running multi-threaded applications, and I believe they're either adding (or maybe have added by now, I'm not sure) the ability to run multi-process as well. Passenger seems to be able to work in every model I've listed above.
I hope this helps a little. It should at least give you some things to Google for to find more information.

Ruby rack app on 1 CPU - how many processes should I run?

I'm quite new to Ruby web apps (coming from java).
I have VPS that has 1 CPU and 2GB of RAM and would like to play with some rails/sinatra stuff.
I'm using Ruby 2.1.0 MRI
How does number of CPUs maps to number of web server's processes I need to run? I use puma as a web server and have default threads (0,16) set up. But I noticed there is also "workers" option that forks another process to better handle multiple requests.
Do I understand correctly that for such setup (1 CPU) there is no point in running 2 web server processes? The only reasonable setup is 1 process with threads?
Oh now this is a pretty big question!
The number of processes and threads aren't necessarily linked to the number of CPU's. It's more a case of the amount of memory available, the amount of concurrent requests and the amount of 'locking' stuff that's going on.
If you're going to have long running requests that block other requests, then having additional processes can help with that. You can still have more than one process with a single CPU.
There are a number of different servers in Ruby that handle scaling in different ways, Unicorn, Puma, Thin are some of them. Doing a search on Unicorn vs Puma vs Thin can turn up some useful blog posts on the topic.
Here's a couple
http://ylan.segal-family.com/blog/2012/08/20/better-performance-on-heroku-thins-vs-unicorn-vs-puma/
https://www.engineyard.com/articles/rails-server
https://www.ruby-forum.com/topic/1822610
And some information on concurrency in Ruby
http://merbist.com/2011/02/22/concurrency-in-ruby-explained/
The TL:DR answer is, it depends!

Rails (3) server - what to use nowadays?

I've been using Ruby Enterprise Edition and Passenger (for Apache, since I run Apache anyway for other things) for some time, but I'm wondering if there's a new trend about what to use on servers nowadays.
For example I've heard about Thin, Unicorn... I also know that 1.9.2 is faster than REE, but I wonder about RAM consumption. I'd rather have it consume less RAM even at the expense of some speed.
Thanks for all advice.
If you want minimal memory you should try Thin.
It does not have master worker as Unicorn or Passenger, thus uses less memory.
Suppose you have a very small app that needs to run on a small VM, then you can use 1 thin worker + nginx. I ran several rails 3.2 apps using Thin+nginx+postgres on 256MB VMs without swapping.
Unicorn is faster but it needs a master worker. It's good if you want to run on Heroku, you can set it 2 or 3 workers and be within the 512MB limit.
If your app is very big and you have too many long running requests, I would check out jRuby and Thinidad/Torquebox.
I converted a few apps from MRI+Sidekiq to jruby+Trinidad+Trinidad_Scheduler. I get about 100-200 req/sec using a pool of 50 threads in a trinidad server!
What I like about jRuby is that you can combine everything on one Rails Server. You can put together on the same JavaVM the cache_store with EHcache, Scheduling, Background processing and real multithreading.
You don't need to run redis, memcached, resque or sidekiq separately.
Im not saying they are not good, I love sidekiq and resque, but you can decrease your complexity by combining everything on one process and have high concurrency.
A more advanced and Enterprise solution is Torquebox, it has support for clustering and is super scalable. But I've had problems with my app crashing on torquebox, so i'm sticking to Trinidad for now.
The disadvantages of jRuby? MEmory! A Trinidad server will use minimum 512MB, up to 2-3GB ram.
Also, for Single Thread server, a single request from a rails app running Ruby-1.9.3 is about twice as fast as the same request on jRuby.
Another option is Puma, you can get full multithreading on MRI with puma. I myself could not get it stable enough on my apps.
So, it all depends on your requirements, memory usage, full threading and concurrency.
Apart from Passenger, have a look at Unicorn, Trinidad, Puma and Torquebox. Those seems to be the top rails servers right now.
There is an great book with an introduction of converting your Rails app to jRuby and deploy your app using several methods such as trinidad.
http://pragprog.com/book/jkdepj/deploying-with-jruby
The Torquebox Documentation is amazingly good. It's very detailed and explains really good how to use all Torquebox features.
http://torquebox.org/documentation/
I Hope that sharing my experience has helped.
Passenger is still extremely strong, especially being REE will naturally support 1.9 in the near future. The fact that your application can crash, however it won't affect anything else on your machine is an amazing feature to have. Deploying code is extremely easy because the server will continue to accept connections, which means less frustration/stress for you.
However, in terms of comparisons:
Here is a great resource is check out various comparisons(including memory consumption) with all the new servers.
It compares Thin, Unicorn, Passenger, TorqueBox, Glassfish, and Trinidad:
http://torquebox.org/news/2011/03/14/benchmarking-torquebox-round2/
Mike Lewis' link does a good job of comparing those different ruby servers. My personal experience has been with nginx/REE/Passenger and its been good. I haven't tried the others, so I can't comment on that.
However, I can speak on RAM usage. Your biggest savings of RAM will come from using 32-bit servers. In my experience (3x 3GB app servers), 64-bit REE/passenger processes took up to 2x as much RAM as their 32-bit counterparts. We saw a significant performance increase moving from 64 to 32 bit servers, everything else staying the same. Unless your application requires 64-bit, I would suggest running your application servers (not database) in 32-bit.
Passenger is still a very good choice to use so you are not behind the times or anything. It is also actively supported and has a very good development team that contributes a lot to the community. We have been using Unicorn and it has been very good. Our favorite functionality is to be able to upgrade apps/ruby/nginx without dropping a connection.

memory requirement for jruby +rails+mongrel?

hi
I am planning to run jruby (1.5.3 latest) on mongrel but how much memory will it require on x64 server for a simple web site ? and how many instances will be required ?
10000 page views per day
for the same requirement what would be the numbers for ruby.
any reference production data would be welcome.
You probably won't use mongrel with jruby, at least i've never heard of it. We run an app using trinidad, which wraps tomcat7 and for similar performance to what you're looking for I use a 1gb heap.
Mongrel has really gone out of favour for more robust setups using passenger or thin or unicorn for instance.
If you're limited with memory, from my experience CRuby is the way to go. Try REE or ruby-1.9.2 with Passenger3 and nginx. It's a super simple setup and very fast.
JRuby definitely takes more memory, but if you have java requirements you don't have much choice.
10000 page views you should get away with a small ec2 instance (if that's what your instances refers to)
It's really hard to give a definitive answer though as it all depends on what type of app you're running. is it cpu intensive calculations, or memory intensive data?? who knows
From my experience, CRuby tends to be much simpler than JRuby, easier for local use (ie tests run significantly faster in cruby) and also very fast.

Resources