(その後、ある程度の回避ができたので題名修正しました。)
Redmineを開発環境の基盤ツールとして使うと、最初からWiki/掲示板/ファイル共有が整うので、開発環境を構築する身にはうれしい話ですが、ファイル共有に関しては課題があります。それは、Redmine(というよりはRuby on Rails)が大きなファイルを扱うのに向いてないということです。ここでいう大きなファイルとは、DVDのISOイメージ等で1つのファイルで数GBの大きさです。
ソフトウェア開発環境では、開発ツールのインストールイメージを共有しておきたいので、DVDのISOイメージファイルを扱いたいというニーズがあります。
この場合の問題点として
- ファイルのアップロードに非常に時間がかかる
- あげくアップロードに失敗する
があります。
実験
CentOS 6.3、Redmine 2.2.1、Passenger、Apacheの環境で1GBメモリ、32GBディスク(KVM仮想ゲスト)空きディスクが18GBという環境で、5GB弱のファイルをRedmineにアップロードしてみた。
結果は、ブラウザにはInternal Server Errorが表示、Redmineのログには次のエラーが残ってました。
Saving attachment '/var/lib/redmine-2.2.1/files/130113040148_sample.iso' (4915200000 bytes) Completed 500 Internal Server Error in 150945ms Errno::ENOSPC (No space left on device - /var/lib/redmine-2.2.1/files/130113040148_sample.iso): app/models/attachment.rb:111:in `write' app/models/attachment.rb:111:in `block in files_to_final_location' app/models/attachment.rb:107:in `open' app/models/attachment.rb:107:in `files_to_final_location' lib/plugins/acts_as_attachable/lib/acts_as_attachable.rb:84:in `block in save_attachments' lib/plugins/acts_as_attachable/lib/acts_as_attachable.rb:80:in `each' lib/plugins/acts_as_attachable/lib/acts_as_attachable.rb:80:in `save_attachments' app/models/attachment.rb:239:in `attach_files' app/controllers/files_controller.rb:45:in `create'
このとき、ディスクの残り容量がやけに少ないので、しらべると/tmpで大きな容量を占めていました。そこで、/tmpディレクトリを見ると
4800000 /tmp/RackMultipart20130113-27685-1g47rji 4800000 /tmp/RackMultipart20130113-31845-1r5t7o8
のように、なぜか2つ今回アップロードしたファイルと同じサイズのファイルが置かれています。
どうやら、/tmpとredmineのfilesディレクトリと3箇所に5GBのファイルが過渡状態として作られ、15GBほど食ってしまっていたようです。
ディスク空き領域を増やして再実験
ディスクを増やして再実験してみたところ、20分ほど時間がかかりましたがアップロード成功しました。
さて、次はこのファイルをダウンロードしてみます。
「接続がリセットされました」
redmineのログでは、
Sent file /var/lib/redmine-2.2.1/files/130113154459_sample.iso (0.2ms) Completed 200 OK in 757ms (ActiveRecord: 654.2ms)
と正常終了したことになっています。
apacheのログにも残っていないので、topコマンドで様子をみながらダウンロードしてみました。すると、
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 1830 apache 20 0 3020m 726m 464 S 5.7 72.9 0:08.13 httpd 1505 apache 20 0 348m 100m 684 R 23.0 10.1 6:25.42 ruby
とhttpdプロセスがどんどんメモリ肥大しているのが分かりました。このとき、スワップファイルもどんどん消費し、スラッシング状態になっています。
http://d.hatena.ne.jp/torutk/20120413/p1 で以前対処したことがある問題でした。
Ruby on Rails 3では対処方法が変更になっています。日記内のリンク先にRails 3での処置方法が言及されています。それを参照しながら確認した結果を以下ページに追記しました。
http://www.02.246.ne.jp/~torutk/swetools/redmine/setupCentOS6.html#xsendfile
Railsの大きなファイルのアップロード
最初はRedmine Large fileをキーワードにぐぐってましたが、Redmine自体がファイルアップロードを作りこんでいるのではないので、Railsに変えて少しぐぐってみると、次の記事を見つけました。
http://www.jedi.be/blog/2009/04/10/rails-and-large-large-file-uploads-looking-at-the-alternatives/
ちょうど同じようなことをしていました。/tmpにできた2つのファイルについても言及しています。Passengerについても言及していて、どうやらアップロード中にメモリ増大という問題があるようです。