Ruby Enterprise Editionを使って、Railsアプリの使用メモリ量を削減(43.5%カット)してみた

ある事情で、サーバ上で多数のRailsアプリケーションを動かす必要性にせまられたので、1Railsアプリあたりの使用メモリ量を少しコンパクト化するべく、「Ruby Enterprise Edition」(REE)を試してみたところ、確かにメモリ使用量が削減された結果(当方例で約43.5%減)になったので、そのメモをエントリに残しておきます。

Ruby Enterprise Edition (REE) とは

マイコミジャーナルから引用させていただくと、、、

REEはCRubyをベースにして開発されている実行環境。オフィシャルのCRubyと比較して平均で33%ほどRailsアプリケーションが使用するメモリ量を削減できるという特徴があるほか、実行パフォーマンスも改善される。

REEにおける性能向上の仕組みはガベージコレクタに対してCopy-on-Write拡張を導入することと、メモリアロケータ (tcmalloc)を改善する方法がベースになっている。最初のプロダクトは数ヶ月以上前から公開されており、すでにNew York TimesやShopify、37signalsなどの企業が自社のRubyアプリケーションの実行環境をREEへ移行している。

http://journal.mycom.co.jp/news/2008/12/09/019/index.html

とのこと。
メモリ使用量の削減に加えて、実行パフォーマンスも改善されるという優れもの。
ただし、Rubyはバージョン1.8.6ベースのものとなるので、この点は注意が必要です。

REEとPassengerのインストール

ソースコードやバイナリは、以下URLからダウンロードできます。

尚、Ruby Enterprise Editionをインストールすると、PassengerRailsなども同時にインストールされます。


Ubuntuな方は、debファイルが準備されているので、dpkgコマンドで容易にインストールが可能です。

私は、今回Fedoraで動作確認をしましたので、ソースコードからビルド(コンパイル)してインストールを行いました。

$ wget http://rubyforge.org/frs/download.php/57097/ruby-enterprise-1.8.6-20090520.tar.gz
$ tar zxvf ruby-enterprise-1.8.6-20090520.tar.gz

お約束ですが、まず、ダウンロード〜展開します。

$ sudo ./ruby-enterprise-1.8.6-20090520/installer

で、インストールコマンドの実行です。

Welcome to the Ruby Enterprise Edition installer
This installer will help you install Ruby Enterprise Edition 1.8.6-20090520.
Don't worry, none of your system files will be touched if you don't want them
to, so there is no risk that things will screw up.

You can expect this from the installation process:

  1. Ruby Enterprise Edition will be compiled and optimized for speed for this
     system.
  2. Ruby on Rails will be installed for Ruby Enterprise Edition.
  3. You will learn how to tell Phusion Passenger to use Ruby Enterprise
     Edition instead of regular Ruby.

Press Enter to continue, or Ctrl-C to abort.

インストーラが起動しました。Enterを押しましょう。

Checking for required software...

 * C compiler... found at /usr/bin/gcc
 * C++ compiler... found at /usr/bin/g++
 * Zlib development headers... found
 * OpenSSL development headers... found
 * GNU Readline development headers... not found

Some required software is not installed.
But don't worry, this installer will tell you how to install them.
Press Enter to continue, or Ctrl-C to abort.

私の環境では、関連するライブラリが足りないみたいです。"GNU Readline development headers"だけがnot foundです。
ということで、Enterを押しましょう。次に、足りないライブラリをどうやってインストールするべきかを教えてくれます。(便利!)

--------------------------------------------
Installation instructions for required software

 * To install GNU Readline development headers:
   Please run yum install readline-devel as root.

↑んな感じで「rootで"yum install readline-devel"を実行してちょ」と言われるので、

# yum install readline-devel

を実行した後に、

$ sudo ./ruby-enterprise-1.8.6-20090520/installer

と、再度Ruby Enterprise Editionのインストーラを実行すると、、、

Checking for required software...

 * C compiler... found at /usr/bin/gcc
 * C++ compiler... found at /usr/bin/g++
 * Zlib development headers... found
 * OpenSSL development headers... found
 * GNU Readline development headers... found
--------------------------------------------
Target directory

Where would you like to install Ruby Enterprise Edition to?
(All Ruby Enterprise Edition files will be put inside that directory.)

[/opt/ruby-enterprise-1.8.6-20090520] :

今度は、ライブラリチェックを通過し、インストール場所を聞かれます。
デフォルトでは、下部の"[]"で囲まれた部分にインストールされますので、デフォルトの場所でOKの場合は、何も入力せず、そのままEnterを押しましょう。
変更する場合は、そのパスを入力した後に、Enterを押します。

--------------------------------------------
Ruby Enterprise Edition is successfully installed!
If want to use Phusion Passenger (http://www.modrails.com) in combination
with Ruby Enterprise Edition, then you must reinstall Phusion Passenger against
Ruby Enterprise Edition, as follows:

  /opt/ruby-enterprise-1.8.6-20090520/bin/passenger-install-apache2-module

Make sure you don't forget to paste the Apache configuration directives that
the installer gives you.


If you ever want to uninstall Ruby Enterprise Edition, simply remove this
directory:

  /opt/ruby-enterprise-1.8.6-20090520

If you have any questions, feel free to visit our website:

  http://www.rubyenterpriseedition.com

Enjoy Ruby Enterprise Edition, a product of Phusion (www.phusion.nl) :-)

インストールが完了すると、↑な感じで"Ruby Enterprise Edition is successfully installed!"と表示されます。


PassengerをApacheに組み込み

この辺は、以前のエントリに細かく書いたので、そちらを参照してください。

もちろん、事前にApacheはインストールしておきましょう。
Apacheのインストール方法については、上記のエントリでも触れていますし、Google先生もたくさん導いてくれるかと。

/opt/ruby-enterprise-1.8.6-20090520/bin/passenger-install-apache2-module

インストールコマンドだけ紹介しておくと、上記のような感じです。
# "/opt/ruby-enterprise-1.8.6-20090520"に、REEをインストールした場合です。

実際に使用メモリ量が減少するか確認


比べたのは、Ruby Enterprise Edition(1.8.6ベース)と、素のRuby(1.8.6)の2つで、互いにPassengerで複数のRailsアプリを稼動させて確認しました。

確認に使用したアプリケーションは「SKIP」で、3つの異なるSKIPの環境を1サーバに構築した上で、同時に動かし、それぞれのケース(REE, Ruby)に同じだけの負荷量を与えてみた結果が以下です。

Passengerの設定値

一応、今回の実験で使ったPassengerの設定値を載せておきます。

PassengerHighPerformance on
PassengerMaxPoolSize 10
PassengerMaxInstancesPerApp 1
PassengerPoolIdleTime 300
PassengerMaxRequests 0

RailsEnv production

こんな感じ。
Passengerの設定の詳細については、今度別エントリで記そうかと思います。

Ruby(1.8.6) + Passenger(2.2.2)を使用した場合

Passengerには、"passenger-memory-stats"という、現在Passengerが使用しているメモリの状況を確認できるナイスなコマンドが添付されています。
このコマンドで、一定の負荷量をかけた3つのSKIPのメモリ使用量を確認してみます。
まずは、素のRuby(1.8.6)では、以下のような結果となりました。

--------- Passenger processes ---------
PID    Threads  VMSize   Private  Name
---------------------------------------
27100  18       10.5 MB  0.6 MB   /usr/lib/ruby/gems/1.8/gems/passenger-2.2.2/ext/apache2/ApplicationPoolServerExecutable 0 /usr/lib/ruby/gems/1.8/gems/passenger-2.2.2/bin/passenger-spawn-server  /usr/bin/ruby  /tmp/passenger.27092
27101  2        18.0 MB  4.7 MB   Passenger spawn server
27136  1        46.5 MB  29.0 MB  Passenger ApplicationSpawner: /var/www/passenger/../skip02
27150  1        66.7 MB  47.5 MB  Rails: /var/www/passenger/../skip02
27152  1        66.6 MB  47.5 MB  Rails: /var/www/passenger/../skip02
27153  1        46.5 MB  29.0 MB  Passenger ApplicationSpawner: /var/www/passenger/../skip01
27168  1        65.0 MB  45.9 MB  Rails: /var/www/passenger/../skip01
27169  1        46.5 MB  28.9 MB  Passenger ApplicationSpawner: /var/www/passenger/../skip03
27179  1        64.4 MB  45.2 MB  Rails: /var/www/passenger/../skip03
27181  1        65.0 MB  45.8 MB  Rails: /var/www/passenger/../skip01
27183  1        66.7 MB  47.6 MB  Rails: /var/www/passenger/../skip01
27185  1        66.8 MB  47.7 MB  Rails: /var/www/passenger/../skip01
27187  1        66.8 MB  47.7 MB  Rails: /var/www/passenger/../skip01
### Processes: 13
### Total private dirty RSS: 467.23 MB

実際に使用している物理メモリ量は"467.23MB"です。

Ruby Enterprise Edition(1.8.6-20090520) + Passenger(2.2.2) を使用した場合

それに対して、Ruby Enterprise Edition(1.8.6ベース)を使用した場合の結果は、、、

--------- Passenger processes ---------
PID    Threads  VMSize   Private  Name
---------------------------------------
28041  18       10.5 MB  0.6 MB   /opt/ruby-enterprise-1.8.6-20090520/lib/ruby/gems/1.8/gems/passenger-2.2.2/ext/apache2/ApplicationPoolServerExecutable 0 /opt/ruby-enterprise-1.8.6-20090520/lib/ruby/gems/1.8/gems/passenger-2.2.2/bin/passenger-spawn-server  /opt/ruby-enterprise-1.8.6-20090520/bin/ruby  /tmp/passenger.28032
28042  1        15.6 MB  5.3 MB   Passenger spawn server
28066  1        48.0 MB  24.9 MB  Passenger ApplicationSpawner: /var/www/passenger/../skip01
28083  1        51.2 MB  28.4 MB  Rails: /var/www/passenger/../skip01
28085  1        51.2 MB  28.3 MB  Rails: /var/www/passenger/../skip01
28096  1        48.0 MB  6.8 MB   Passenger ApplicationSpawner: /var/www/passenger/../skip02
28114  1        51.2 MB  25.3 MB  Rails: /var/www/passenger/../skip02
28116  1        48.1 MB  6.8 MB   Rails: /var/www/passenger/../skip02
28119  1        51.2 MB  28.2 MB  Rails: /var/www/passenger/../skip01
28125  1        52.2 MB  28.9 MB  Rails: /var/www/passenger/../skip01
28128  1        51.2 MB  27.1 MB  Rails: /var/www/passenger/../skip02
28152  1        48.0 MB  25.0 MB  Passenger ApplicationSpawner: /var/www/passenger/../skip03
28164  1        51.2 MB  28.5 MB  Rails: /var/www/passenger/../skip03
### Processes: 13
### Total private dirty RSS: 264.22 MB

Ruby Enterprise Editionだと、実際に使用している物理メモリ量は"264.22MB"と激減しました!

今回は厳密に計測していないので、今回の結果の値からは、多少上下するとは思いますが、今回の前提で計測した場合、メモリは、約43.5%ほど削減されたことになります。

すげぇな、Ruby Enterprise Edition。


もちろん、稼動させるアプリケーションや、Passengerの設定にも左右されるとは思いますが、使用メモリ量の削減には大きく貢献してくれそうなので、試してみる価値はありそうですよ!

時間があれば、今度はパフォーマンスの違いを計測してみたいと思います。

参考


Railsデプロイ

Railsデプロイ

  • 作者: Ezra Zygmuntowicz,Bruce A. Tate,Clinton Begin,前田修吾(監訳),橋本将(監訳),小倉正充(監訳),牧野聡
  • 出版社/メーカー: オライリージャパン
  • 発売日: 2009/03/16
  • メディア: 大型本
  • 購入: 25人 クリック: 209回
  • この商品を含むブログ (31件) を見る

実践 Rails ―強力なWebアプリケーションをすばやく構築するテクニック

実践 Rails ―強力なWebアプリケーションをすばやく構築するテクニック