第2回 rsyncを用いたコンテンツの分散
内間 圭介
株式会社Cuon
2008/10/16
Rubyを使った大規模エンタープライズ開発が始まっている。Ruby on Railsでの開発において、インフラやアプリケーションアーキテクチャをどのように構成すべきかを考える(編集部)
第1回「CGMサイト構築で悩む負荷対策と拡張性の確保」では、CGMサイト構築における負荷対策と拡張性の実例をいくつか紹介した。今回は予定を変更して、rsyncを用いたコンテンツの分散について述べる。
ここではユーザー投稿画像などのデータを保存するのに、高価なストレージを導入するのではなく、安価なコンテンツ専用サーバをスケールアウトさせていく方法について説明する。
ここに挙げる方法では、コンテンツサーバをWebアプリケーションサーバにマウントしない方針を採用している。これはRuby on Rails(RoR)が本来想定している環境と異なり、それなりのデメリットもあるが、スケールアウトの容易さを優先させた結果である。
それでは、コンテンツサーバをWebアプリケーションサーバにマウントせず、rsyncを用いてコンテンツを転送する例を実際のコードを交えて示そう。
コンテンツサーバの分離
第1回にも述べたが、弊社が開発したコミュニティサイト「ライフパレット」では、画像などを保存するコンテンツサーバをマウントしない方式を採用した。これはWebアプリケーションサーバやコンテンツサーバが増えた場合のマウントの手間を省き、単純なスケールアウトを実現するためである。
Webアプリケーションサーバに加え、コンテンツサーバもスケールアウトすることを考えると、台数が増え、複数Webサーバ−コンテンツサーバ間で「たすき掛け」形式でマウントが実施された際の信頼性に対する不安がある。またマウントそのものの手間も増大する。
そこで、より簡潔で単純なスケールアウトを実現するために、コンテンツサーバをマウントするのをやめ、rsyncでWebアプリケーションサーバからコンテンツサーバへ画像を転送することにする。
コンテンツサーバの情報(サーバのIPやデータ保存先ディレクトリなど)はデータベースに格納し、Webアプリケーションサーバはデータ転送時にこれを参照する。コンテンツサーバが増えた場合には、データベースに新しいコンテンツサーバの情報を追記するだけでいい。なお、Webアプリケーションサーバが増えた場合には、コンテンツサーバに対する作業は発生しない。
このようにすることで、Webアプリケーションサーバとコンテンツサーバは独立してスケールアウトできるようになる。
またこの場合、コンテンツサーバに格納された画像は、Webアプリケーションサーバ(mongrel)からは配信されず、コンテンツサーバからロードバランサを通して配信される。
画像へのURLにはコンテンツサーバの識別子が埋め込まれており、これを見てロードバランサは各コンテンツサーバに画像を要求し、コンテンツサーバに立てられたlighttpdが画像を返す。画像配信に関しては、Webアプリケーションサーバを介さないため、これはWebアプリケーションサーバの負荷分散にもなっている。
file_columnによる画像管理
画像アップロードとサムネイル生成などのサイズ変更には、Railsでは一般的なfile_columnプラグインを利用している。file_columnプラグインは、アップロードされたファイルの情報を、対象モデルのテーブルカラムに格納する。例えば、記事モデルが画像を1枚持つ場合、以下のような指定をする。
# 記事モデル |
しかし、このままだと記事が持つ画像ファイルが増えるたびにカラムも追加しなければならない。Railsの場合、マイグレーションの追加・変更が生じてしまう。
これを解決するため、画像カラムだけを別モデルとして分離する。分離された画像モデルは、記事だけでなく複数の親モデルから参照されることが期待されるので(記事画像、ユーザー画像、コミュニティ画像など)、親モデルとの関連にはポリモーフィック関連を利用する。
画像モデルを別モデルに分離した場合のコードは、以下のようになる。このコードでは、file_columnのオプションで、画像ファイル保存先の指定やサムネイル生成などをしている。
# 記事(親モデル) |
ここで説明するfile_columnの基本的な使い方として、上記のようにオプションで画像保存先が指定できることと、以下のように「オブジェクト.カラム名_dir」というメソッドで、画像保存先ディレクトリが取れることが分かっていれば十分である。
$ ruby script/console |
1/3 |
Index | |
rsyncを用いたコンテンツの分散 | |
Page1 コンテンツサーバの分離 file_columnによる画像管理 |
|
Page2 画像保存先ディレクトリをどう指定するか file_columnによる動的な画像保存先変更 |
|
Page3 rsyncによる画像転送 実装コストを取るか、運用コストを取るか |
RoRでCGMサイト構築虎の巻 |
Ruby/Rails関連記事 |
プログラミングは人生だ まつもと ゆきひろのコーディング天国 ときにプログラミングはスポーツであり、ときにプログラミングは創造である。楽しいプログラミングは人生をより実りあるものにしてくれる |
|
生産性を向上させるRuby向け統合開発環境カタログ Ruby on Rails 2.0も強力サポート 生産性が高いと評判のプログラミング言語「Ruby」。統合開発環境を整えることで、さらに効率的なプログラミングが可能になる |
|
かんたんAjax開発をするためのRailsの基礎知識 Ruby on RailsのRJSでかんたんAjax開発(前編) 実はAjaxアプリケーション開発はあなたが思うよりも簡単です。まずはRuby on Railsの基礎知識から学びましょう |
|
Praggerとnetpbmで作る画像→AA変換ツール Rubyを使って何か面白いものを作ってみよう! 一般的な画像をアスキーアートに変換するツールを作ってみる。さらに出力にバリエーションを持たせてみよう |
|
コードリーディングを始めよう Railsコードリーディング〜scaffoldのその先へ〜(1) 優れたプログラマはコードを書くのと同じくらい、読みこなす。優れたコードを読むことで自身のスキルも上達するのだ |
|
- プログラムの実行はどのようにして行われるのか、Linuxカーネルのコードから探る (2017/7/20)
C言語の「Hello World!」プログラムで使われる、「printf()」「main()」関数の中身を、デバッガによる解析と逆アセンブル、ソースコード読解などのさまざまな側面から探る連載。最終回は、Linuxカーネルの中では、プログラムの起動時にはどのような処理が行われているのかを探る - エンジニアならC言語プログラムの終わりに呼び出されるexit()の中身分かってますよね? (2017/7/13)
C言語の「Hello World!」プログラムで使われる、「printf()」「main()」関数の中身を、デバッガによる解析と逆アセンブル、ソースコード読解などのさまざまな側面から探る連載。今回は、プログラムの終わりに呼び出されるexit()の中身を探る - VBAにおけるFileDialog操作の基本&ドライブの空き容量、ファイルのサイズやタイムスタンプの取得方法 (2017/7/10)
指定したドライブの空き容量、ファイルのタイムスタンプや属性を取得する方法、FileDialog/エクスプローラー操作の基本を紹介します - さらば残業! 面倒くさいエクセル業務を楽にする「Excel VBA」とは (2017/7/6)
日頃発生する“面倒くさい業務”。簡単なプログラミングで効率化できる可能性がある。本稿では、業務で使うことが多い「Microsoft Excel」で使えるVBAを紹介する。※ショートカットキー、アクセスキーの解説あり
|
|