My rails sites run Mongrel, I am having a problem with the amount of memory being used. My ruby-bin processes are using up about 66 MB of resident memory. How can I reduce the amount of memory used by rails?
It is not very economical to have many rails servers running on a single machine if they are eating memory at this rate. My php5 fcgi processes sit at between 15-25 MB.
I'm fairly unfamiliar with RoR, would using JRuby help? Any comments helpful in reducing memory footprint and increasing performance are more than welcome.
You might look at Phusion Passenger and Ruby Enterprise Edition, which is the de facto standard setup for Rails apps these days. One of its aims is cutting memory use. It's also simpler than having a bunch of Mongrels.
If you are not tied to apache for something else, i would also try nginx with Phusion Passenger. If you're concerned about memory usage, you should see a smaller footprint from nginx than apache, and the lastest version of Passenger will download, compile and install nginx for you with minimal headaches.
You can also replace your mongrel process with Thin which is more efficient and has recently been patched in its Garbage Collection (thru eventmachine), to make it even better.
We use thin cluster behind nginx frontends with fine results.
I wouldn't go so far as to say Passenger is the de facto standard, but it's gaining a lot of traction. We just switched to Nginx+Passenger, and our ruby app (i.e. Mongrels vs. Passenger) memory footprint dropped from about 450MB to 295MB. It can drop less, as Passenger will kill off procs if they idle (this is configurable), but of course if you're getting traffic and it's using all of the instances you have it configured to, then they'll use up memory accordingly.
Note, that we are not using Ruby Enterprise Edition in our config yet (mainly because it's not yet available at Engine Yard), but we still are seeing a smaller memory footprint. Memory was the initial top reason we made the switch, but there are other benefits, such as faster and easier configuration for scaling up or down, and so on.
Related
I've been searching around for performance tests on the new passenger 5 as I read here it became way faster.
I tried to find other ressources confirming this but no luck. Has anyone tried to install it and see the difference?
Passenger 5 scores better on custom-picked benchmarks because it has a built-in caching layer ("turbocaching") that can avoid actually running your application code for identical requests in a short timeframe; it will not make your actual application code run any faster. This caching layer is only active in certain constrained situations, and is not likely to provide much benefit in the vast majority of actual cases. If you aren't careful, the caching layer may actually end up breaking your application - I demonstrated several security vulnerabilities due to the caching layer to Phusion during the 5 beta phase (which they fixed, at the cost of the caching layer not being able to cache nearly as much). IMO, the Raptor/Passenger 5 benchmarks are deceptive marketing fluff, and the caching layer exists primarily to win Hello World benchmarks, and you should probably just ignore them.
That said, the speed of your application server is almost certainly insignificant in the scope of your overall application performance. Passenger is a great platform because it's extremely user-friendly, well-documented, has an absolutely fantastic installer, and handles a lot of the annoying crap for you out of the box. You should use Passenger if you need the functionality it provides and don't want to screw around with a ton of config stuff. If it doesn't fit your use case, use something else that does.
If every last microsecond is of prime concern to you, you should measure your application's performance under various webservers and various workloads, and then pick the one that performs the best. Otherwise, use whatever you like the most and then switch once performance becomes an actual problem.
Footnote: If you do use Passenger 5, be sure to read the Turbocaching security changes article to be sure you don't accidentally make your application vulnerable to user data theft (or otherwise introduce bugs) through the turbocaching layer.
I recently migrated my app from Puma to Passenger.
I have to say that I'm really happy about this move, especially because I'm hosting it on Heroku.
Since I updated to Ruby 2.2, I had some memory issues with Puma due to Heroku memory limitation (512M).
I tried a couple of different configurations but without success.
Since I moved to Passenger, I saw the memory usage go down to almost half what I was consuming with Puma with the same number of server instances (3 in my case).
Regarding the response time, it seems to be pretty much the same as before but with those memory improvements. Although, I reduced my number of Heroku dynos to handle the same number of requests.
In conclusion, on my personal experience, Passenger helped me a lot reducing the memory used by the app but it didn't helped improving the average response time. Another good point is, regarding the Heroku pricing, it helped me a lot to reduce the cost of my hosting.
I know this post is not really exhaustive without any benchmarks etc... But I thought that maybe you could find it interesting to have a personal experience on a migration from Puma to Passenger.
Hope it helps :)
First of all, let's just be clear, when we talk about server performance, the question is about how well the server scales as usage increases. If your server has one or very few human users, for most apps, you will get the same end-user experience regardless of which server you use because the bottle-neck will be the performance of Ruby, not the app server.
For medium and large apps:
So let's talk about scaling. The more CPU power and RAM you have, the more you can scale. Most servers run out of RAM faster than CPU power. So the key is to minimize the amount of RAM used per request. Each request the server receives will be handled by a process or a thread. Processes use a lot of RAM, threads use very little RAM. So the goal is simply to have lots of threads and few processes.
Puma and Passenger Enterprise are both multi-threaded servers which will scale approximately the same. (Passenger's benchmarks claim to use 5MB less RAM per process, but this is negligible.) Passenger itself (the free version) is single threaded and will not scale as well as the paid Passenger Enterprise version or as well as Puma.
So if you want maximum performance, you're choosing between Puma and Passenger Enterprise. The question then becomes, is Passenger Enterprise worth the financial cost vs is Puma worth the technical expertise cost. The answer depends on what's in your brain(s), what's in your bank account(s), and your general opportunity cost.
Passenger Enterprise has some nice tools that hold your hand if you're not an expert system administrator. Puma also has some tools but they are not as powerful as what Passenger Enterprise provides. Puma requires system-level expertise if you want to get the same control and insights as Passenger Enterprise. (You can also use Puma without all the bells-and-whistles of Passenger Enterprise, but I want to keep this comparison "apples-to-apples").
Personally, I'm a low-level guy who loves configuring servers so I prefer to trade my time rather than my money for an awesome Ruby server. Therefore, I use Puma. If you're not interested in configuring low-level stuff (or if you're a company that realizes software licenses are cheaper than administrator-developers), you might be better off with a paid Passenger Enterprise license.
For the guy running a $5 VPS (or similar low-resource, low-traffic environment):
What I said above is more for higher-traffic apps on servers with considerable resources. You're just trying to get by with basics, so it does not really apply to you.
Think of Puma and Passenger Enterprise as jumbo jets that can move a lot of people very fast. That's way more than your little app needs. What you really need is the server equivalent to a Honda Civic. For that, you should consider either the free version of Passenger or Thin. Use free Passenger if you want easy setup and decent tools. Use thin if you want similar performance but have a willingness to engineer the server.
In this case, I see no reason to use anything but free Passenger unless you are looking for a challenge.
As others said, Passenger by itself doesn't make your app faster per se. Passenger itself has become a lot faster in version 5, but the app server is only a part of the response time. If your app is slow, then it doesn't matter how fast Passenger itself is.
Having said that, Passenger differentiates itself from other app servers by actively helping you to make your app faster. Passenger's turbocache is one way through which Passenger helps you. The article Dynamic Site as fast as a Static Generated One with Raptor demonstrates a good use case for the turbocache. Passenger also provides an optimization guide that gives you tips on how to optimize your app using Passenger settings.
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.
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.
This is probably the silliest question today but...
The Rails team & many others recommend using passenger instead of a mongrel cluster, but I cannot find a clear list of exact benefits / advantages of this or what the potential pitfall are. Just wondering if anyone can help explain this?
Also is passenger its own server or does it use mongrel under the hood?
Thanks!
Before Passenger, Mongrel was the way to go, but a Mongrel cluster can be a nuisance to keep properly tuned. As your application grows in complexity, the memory footprint of each Mongrel instance will expand, and this can eat into available disk cache and degrade performance, so you'll have to pay close attention to the memory allocation balance on your deployments. From time to time you'll have to tweak it to add or remove Mongrels.
The other downside is you'll need to manage these Mongrel processes using some kind of launcher like monit and these can be fussy and difficult. Mongrel does not come with its own process manager.
Another serious problem is that each Mongrel is locked to a particular application and shifting loads between one app and another is very difficult to manage.
Mongrel is also dependent on an external load-balancer that you must configure yourself.
Passenger will handle launching all the Rails engine processes and will do its best to allocate memory efficiently. If you have a number of sites with conflicting priorities, Passenger will do a good job of launching servers on demand, and pruning them off when they're not used.
Passenger is also very quick to relaunch all instances of an application by looking for the tmp/restart.txt trigger file. You don't have to kill any processes or wait for a restart.
Under the hood, Passenger uses its own launcher and dispatch system. Although functionally it is similar to Mongrel, there are a number of significant performance improvements that Phusion has introduced that make Passenger significantly more memory-efficient than Mongrel.
Passenger is a complete package that just works and is surprisingly easy to manage. Mongrel is only a very basic web server.
I have a Ruby on Rails application that will be a CMS in way which means it's mostly DB intensive. I expect it to have decent amount of traffic so before designing I'm choosing what servers to use. Most important for me is performance.
I heard good things about Nginx and many developers in the Rails community recommends it my only concern about it was that its version is 0.8 which is Beta I believe so I was concerned about potential problems. What is your say?
Also, I want to decide between using Mongrel cluster or Phusion Passenger. What do you think?
I'm planning to user Ruby 1.9 as it has better performance that Ruby 1.8 and I will be using VPS to host my website.
My main things is performance even if it takes longer to setup one over the other.
Your opinion is highly appreciated.
Thanks,
Tam
I'd second for Passenger + Nginx. Very low memory and it's not too difficult to setup. What type of server are your deploying too? Specs? OS? I'd take that into consideration as well considering your available hardware. If you've got enough memory already, then it shouldn't be an issue whether its Passenger or Apache, just optimize and cache your app efficiently.
Two comments:
You can deploy any rails app to any of your mentioned servers, so no need to decide this once and for all now.
IMO mongrel clusters are no longer worth the trouble. Go for passenger on whatever server makes you happy.
Id recommend passenger nginx, the configs are nice and tidy plus the memory footprint is really low compared to passenger apache.