How to access multiple databases with rails
I know it exists other information about this, but I want to summarize here the practise I use in several project now. It takes 4 steps:
- configure your database.yml
- create an abstract class for connection
- create new models within a module
- interact the 2 databases
1. Configure your database.yml
This is the same as you create production or development connection, just give it a specific name:
2. Create an abstract class for connection
Then create an abstract class you will inheritate by your new classes:
3. Create new models within a module
To make it easier to use and cleaner, create a subfolder OtherDatabase and then create in this folder your new classes (for each table you need) as following:
4. How to interact the 2 databases
Once you have created your new classes, you can simply access it using the module prefix:
Conclusion
That’s all, submodule is not really necessary but keeps your model folder cleaner. Any suggestion to improve this practice ?
Rails: find controller for a path
Huh, seems simple to do :p, but I’ve been seeking for a while to find the answer and dig into rails code to find a simple method to retrieve the controller of a given path (could be useful to build a navigation). There it is:
ActionController::Routing::Routes.recognize_path(path)[:controller]
Ebb, even faster than Thin
Ebb is new server to put in front of a rackable ruby application.
Have a look to the Ebb website to get some comparison with other app servers.
sudo gem install ebb
What I needed to do before on Mac OS X (leopard with MacPorts):
sudo port install glib2
Webby as a powerful wiki-like notebook
Introduction
I have often look at wikis, trying to find a nice tool for taking my notes and formating them. Have many ideas in my head, like to write them down and visualize it. Wiki is great for that but always a bit heavy to “deploy”.
Continuesly seeking for new ruby things, I heard about Webby, a lightweight web publishing system. Simply taking your pages (textile, html, erb, aso…) and generate a static website. Run Heel on it and you will have a perfect light but very powerful wiki-like web site. Extension are perfect for programming notes including graphiz and syntax highlighting.
Setup your notebook
sudo gem install webby
This will install several gems, included heel.
more coming…
Model inheritance with Merb
from help on irc#merb
I had recurrent issue about inherit a model class from another one in Merb, using ActiveRecord or DataMapper. As it’s ‘magicly’ done on Rails I though the same way in Merb, but the last one load model class in alpha order. then what you have to do is to load the first class with a require:
in your first file:
class Page < ActiveRecord::Base end
then in second add the require:
require 'page' class ActivePage < Page end
Simply using ruby…
Most used front end: poll results
For severals month now I put a poll about which front end people use for their website. Even if it s not a reference with only 85 votes I would like to publsih some result. Of course as the content of this website is ruby oriented, then the results will be also.
First it started with most of votes for apache. At the end Apache it’s still the first:
- 47%: apache
- 40%: nginx
- 7% : lighttpd
- 5% : others
The result for nginx is over general real stats but for the trend is here and nginx is more and more the choice for a ruby stack as I did present in my last post
Rmagick on Ubuntu
I found other libraries as librmagick but it seems to have better solution:
# libmagick9-dev ?
sudo apt-get install libmagick++9-dev ruby1.8-dev
wget ftp://ftp.fu-berlin.de/unix/X11/graphics/ImageMagick/ImageMagick-6.3.8-9.tar.gz
tar xzf
./configure —prefix=/usr
make
sudo make install
sudo gem install rmagick
Scaling a Rails app (Part 3 of 3)
This the third and last part for a summary about solutions to help better computing of your rails app
Some home made benchmarks
NB: Following benchmarks have been made to a quick look study and not for a proof of concept.
The test machine (dedibox, ubuntu 6.10) is 1 core cpu @2Ghz – 1024 Mo memory. In each case the http server uses 10 processes on a real world application (not just ‘hello world!’). Sending 500 rq with 1 or 10 concurrency req:
| conc. req. | 1 | 10 |
|---|---|---|
| apache | ||
| mongrel | 39.4s – 12.7 r/s | 21.9s – 22.8 r/s |
| thin | 37.6s – 13.3 r/s | 17.7s – 28,15 r/s |
| nginx | ||
| mongrel | 39.2s – 12.8 r/s | 22.2s – 22.5 r/s |
| thin 0.5.4 | 39.8s – 12.6 r/s | 17.7s – 28.15 r/s |
| thin 0.6.1 socket x2 | 37.6s – 13.3 r/s | 17.8s – 28.1 r/s |
Since last time, Rails world has a new nice app server: thin. Replacement of mongrel, based on rack interface, it’s also recently added a unix socket connector where usually we use IP connector. For better performance, avoid longest stuff as scripts (google analytics). Other scripts/images/css are keys in http performances also, usage of assets in recommended.
As we can see in equivalent configuration there is no major difference for http server. Thin seems to be definitly faster than mongrel when you need to server more than 1 request at a time. And of course on a 1 core cpu, having more than one app server doesnt make the content served really faster.
Memory usage
Mongrel (48 Mo) → Thin (40 Mo) less 15%
Apache (10 Mo) → Nginx (1.4 Mo) less 85%
Finally I decided to move to a nginx / thin on socket configuration because of the memory usage and the fair performances. I even moved my PHP stuff with an fcgi connector.
Other ideas of tests: Varnish, Nginx and memcached. Maybe next time :)
[update]
Please find a good benchmark about nginx vs apache on Joe’s blog
Overall conclusion
I think when we need to compare two framework, about which one is faster, we should keep in mind all these levels of optimisation to scale an application, and then the raw performance is a secondary issue.
Radiant to Merb
Merb is a (future) great framework. Radiant is good CMS. And they have so much in common. I’m curious about porting Radiant to Merb then I started the challenge. For people interested in the same challenge, I set up a repository. Then please feel free to participate.
[update]
I got invited on github then I cloned the git repository to http://github.com/sbusso/merb_radiant/tree/master
Action plan:
Merb is a framework equivalent to Action Pack. It can use Active Record. For generator we can use Rubigen, it s an extract of RailsGenerator.
For this we will use:
- Radiant trunk r742
- Merb (core and more) 0.9.0
- Merb helpers 0.9.0
- Merb ActiveRecord 0.9.0
- ActiveRecord 2.0.2
- Rubigen 1.2.0
The repository tree was build with:
- Hoe (modified) generated skeleton
- Merb application
- Radiant source
1. Move Radiant base:
- use plugins as gem:
* radius 0.5.1
* highline 1.4.0
* rubypants 0.2.0
- use other plugins as ruby libraries:
* bluecloth
- using active record: nothing to do
- radius and other ruby libs: nothing to do
- replace RailsGenerator with Rubigen (Radiant bin)
- work on initializer
- desactivate extension dependencies (first step we move only the base)
- manage Controller and libraries using controllers
- check routes management
- work on views to replace Rails specific code
2. Replace extension system with gems:
- first, activate gem with only code features
- second, deal with extension providing assets
Merb 0.9.0 - only for developer
Following the next version of Merb, I’m a bit surprised by the way this new version came out:
Help of developers is needed for going on 1.0, then install it and try it.
Included :
- merb-core
- merb-action-args
- merb-assets
- merb-gen
- merb-haml
- merb-mailer
- merb-parts
- merb-more
- merb
then
merb-gen myapp
Install ruby memcached on MacOSX
Classical way, download following archives and compile it in the order. Xcode has to be installed.
tar xzf *.tar.gz cd ./configure make sudo make install
Scrubyt on Rails
If like me you have an error after installing scrubyt 0.3.4 (in console and launching mongrel):
can't activate RubyInline (= 3.6.3), already activated RubyInline-3.6.4]
I spent a lot of time to find the solution, and so easy solution … anyway could be useful for people googling about this. You just need to unsinstall the lastest installed version of RubyInline:
sudo gem uninstall RubyInline -v 3.6.4
Everything should be fine with this, even Scrubyt requiring version 3.6.3.
Scaling a Rails app (Part 2 of 3)
This the second part for a summary about solutions to help better computing of your rails app (1st part).
Application
To help your application to focus on replying fast to user, you can use a distributed queueing to give the job to other processes:
And second thing, you can cache things you don’t need to compute for each request, this can incredibly increase the response of your server, but need to modify your code and it s recommend for very big sites:
Back end
DB
For your database you can find some sql proxy, but I haven’t tried it yet. You have also the way to replicate your databse and serve data from several servers.
- sql relay
- use jruby with a jdbc pool connection and caching
Important things you have to check about your databse is if you have the right indexed fields. You should find some tools on mysql helping you to find where indexes missing. Check about cache too.
A last way is to serialize some of your data in a single object.
Mysql
Otherwise you can configure your mysql with some optimized configuration (mysql.ini):
- skip-name-resolve
- query_cache_size = 52428800;
- query_cache_type = 1
And in your ActiveRecord object you can use the :include parameter.
Filesystem
Optimizing the filesystem, in other sense than choose a good OS, can been done with not overloading the management of files by using some rules:
- max 10K files / subdir
- 16 top level / 256 sub / 10K per sub dir
- use a hasher to manage files
OS
As we have seen, file and memory management are keys of good performances. And these are managed by OS. The two best OSs mentionned are
- Sunsolaris
- FreeBSD (can be use for a all in one stack), avoid the version 5
And upcoming, last part of this article, some home made benchmarks for my own purpose.
Scaling a Rails app (Part 1 of 3)
One of the most interesting topic in the RailsConf was Scaling your Rails app. There are 2 ways of doing it:
- adapt your code
- adapt your servers
But the second one will not help to make your code faster. It will just help to give maximum resources to compute it right.
Summaries from the conference (sorry for the so few litterature it will be only a summarize):
Some theories
These theories are for big websites with millions of hits every month. This can involve thousand of servers, different location, … BTW some tips can be use to help smaller configurations.
The 7 layers to be considered, a la OSI.
- DNS
- frontend
- proxy
- application server
- application
- backend (Db , filesystem)
- OS
DNS
Nice website to check your DNS configuration: dnsstuff.com
Good tool to optimize your DNS: speed, dispatching, and so on…: powerdns
DNS can be quite fast to address the right server from a request, scripts allow to manage complex configurations. The tip is to use 1 DNS entry per 1 controller, then managing part of the routing.
Frontend and Proxy
Load balancing is about dispatching requests taking in account the charge of each cluster.
Load balancers:
Varnish
HAProxy
Both look promising and HAProxy seems to be more and more popular.
Front end with load balancer:
Nginx : fast, low memory usage, http server with load balancing, easy configuration, very good in front of mongrel cluster.
Apache 2.2 + mod_proxy_balancer, you can find how to setup it in previous post: apapche, mongrel cluster, rails on a load balancer
Application server
- mongrel server: enough for a personnal server
gem install mongrel
mongrel_rails start (more information) - mongrel_cluster: useful to scale up your configuration, need at least a multi-processor or multi server environnment.
gem install mongrel_cluster
mongrel_rails cluster::configure …
mongrel_rails cluster::start - Evented Mongrel (swiftiply): it’s a mongrel based an event triggering
- jruby / glassfish: the technology java comes with some good environment to speed up part of your application like connection to database (jdbc, pool connection)
to be continued (application, backend, OS, and some home benchmark)
Nginx and Mongrel cluster on debian
Nginx is a ‘small’ efficient http, load balancer server. More and more popular in Rails community, it’s a good front end for mongrel clusters. It’s seems to be a good replacement for apache, at least for the memory usage (on my test: 1 process use 1.3M against the more than 9M taken by 1 apache process). Benchmark on one single server are quite similar.
The process has been tested on debian 4.0r1 and should work on Ubuntu.
Installation
apt-get install nginx
or, if you want an up to date product:
1/ Prepare your system
apt-get install zlib1g-dev libgcrypt11-dev libpcre3-dev libssl-dev
tar xzf nginx-0.6.12.tar.gz cd nginx-0.6.12
3/ Compile it
./configure --pid-path=/usr/local/nginx/logs/nginx.pid \
--sbin-path=/usr/local/sbin/nginx \
--with-md5=/usr/lib \
--with-sha1=/usr/lib \
--with-http_ssl_module \
--with-http_dav_module --prefix=/usr \
--conf-path=/etc/nginx/nginx.conf \
--pid-path=/var/run/nginx.pid \
--lock-path=/var/run/nginx.lock \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log
make
sudo make install
Configuration
The following configuration is for 1 nginx server with load balancing 3 mongrel in cluster:
1/ Mongrel cluster configuration
gem install mongrel_cluster -y cd /var/www/my-app-path/current/
configures 3 mongrel in cluster, in production mode, starting at port 5000 and listening on localhost
sudo mongrel_rails cluster::configure -e production \
-p 5000 -N 3 -c /var/www/my-app-path/current/ -a 127.0.0.1 \
--user www-data
mongrel_rails cluster::start
2/ Nginx
nano /etc/nginx.conf
Use the nginx.conf file from brainspl.at website, change the 2 or 4 (if you use ssl) references to the path of your application (/var/www/my-app-path/current/)
/etc/init.d/nginx start
All these information come from many website (thanks to all), I put them together for my own usage, hope it’s helpfull.
Apache, Mongrel (cluster) and Rails are on a load balancer
Following the conference, and some information about scaling Rails application, I decided to investigate about it and write a post on it.
First, I tried to install FreeBSD as recommended for small configuration… Well, I still don’t get it, I’m not fan of this installation and stop trying to understand, instead I installed a Debian 4.0R1, not so bad and closer to what I know :)
Secondly, I want to try Nginx. First, need to find the good one to install on Debian, not last dev, maybe the one on the testing repository. Finally I found package with the 0.5.31, latest stable version. Easy to install with dpkg, I only wanted to simply configure static server and point on php application I have. Ouch, the php-cgi stuff is pretty much more complicated than expected, I had a look to a Rails configuration and gave up :p.(update: configuration of one server is not so complicated, at least for rails, not more than load_balancer in apache, but it is for php and if you want to dispatch URL on the same domain, it doenst seem trivial)
Then I went back to something I can handle: apache. I have read some article about 2.2 you can use with load_balancer and several mongrel instances. Let’s go for it. I found a very complete article: Time For A Grown-Up Server: Rails, Mongrel, Apache, Capistrano and You used also by mongrel website about Apache Best Practice Deployment.
As I faced some issues, please be careful about the following:
1/ Mods to activate:
a2enmod proxy a2enmod proxy_http a2enmod rewrite a2enmod deflate a2enmod headers a2enmod cache a2enmod mem_cache a2enmod file_cache
2/ Forbidden access ?
If you have some issue with forbidden access please check your proxy conf file and replace
Order deny,allow Deny from all
by
Order allow,deny Allow from all
Enjoy!
I’ll try again Nginx and maybe also pen / pound and litespeed. A buzzy load balancer: HAProxy. A lot of work is coming :p. If you have some feedback about these configuration don’t hesitate to share it :)
Ruby authentication system: Poll results
And the winner of 68 votes is ….
acts_as_authenticated with 47,06% of the votes
followed by
- salt / sugar systems, 35,29%
- other…, 13,24%
- openid, 2,94%
- auth_generator, 1,47%
Congratulations to the winner, it is a very nice and neat plugin. BTW at the RailsConf, we had a demonstration of an HTTP_AUTHENTICATION as a new feature of Rails 2.0. More’s coming…
(Ruby on) RailsConf Europe 2007
The conference has just finished, and the first thing to say “it’s a must go conference for all of you developing with Rails”. These 3 days were plenty of good information and teaching. You can read a lot of things on feeds or blogs, train yourself about every thing in Rails but nothing worth the real contact with the community. 500 750 participants but only 2% of french people “mais ou est la communauté francaise rails ?” and 95% of Mac users :D. Berlin is quite pretty city to visit, that’s was a good plus :).
I will write a serie of posts about some interesting conferences I attended to :
- Scaling rails app
- Security (website)
- Capistrano 2.0 (you should use it)
- RSpec and its stories (good ideas, the best is coming)
- Tavnav and other italian widgets (DRY)
- Rails 2.0 RC (not a revolution, but many nice evolutions)
and maybe another one about feedback of business creation around rails app.
Other subjects I have watched but will not write about:
- Good practises (no big stuff)
- Ferret (previous post)
- Presenter concept (maybe a good idea but not convinced by the presentation)
- REST (already covered by many posts)
I have been disappointed by one thing, there weren’t any RadiantCMS talk :(.
Link_to: presentations and descriptions
Ruby and OpenSSL on Ubuntu
If you try to use scrubyt or mechanize on ubuntu you could get some error like:
no such file to load -- openssl
After having installed Opensll via apt-get you will also need libssl_dev.
sudo apt-get openssl libssl-dev
Then now go to the ruby source folder, and in openssl extension folder: /…/ruby1.8/ext/openssl
<pre>ruby extconf.rb
make
sudo make install</pre>
check your installation with ruby -rubygems -e "require 'mechanize'"
Radiant 0.6.0 is out
Congratulation to the team of Radiant CMS they have released a great piece of code with this version:
$ sudo gem install radiant
Enjoy !
Weekly Rails Digest - March 25, 2007
Not a big digging week, at least some nice links:
- Geokit: a Rails plugin for building location-based apps.
- Gooby: a ruby interface to the google api, now version 1.
- Ruby 1.8.6: no comment, just for those who didn’t know :).
- WhatALi.st: GTD website or how to share and work all together on list, whatever list.
For this week, that’s all folks.
New Ruby website
For those who haven’t seen yet, the new ruby-lang website is out. Working on it for long time, the members of the community did a great job with this new design and use Radiant CMS to power it.
Please find it and the latest 1.8.5 version of ruby on the website : http://www.ruby-lang.org/en/