第4回 memcachedで快速アプリケーション
太田 哲也
株式会社Cuon
2008/2/25
Rubyを使った大規模エンタープライズ開発が始まっている。Ruby on Railsでの開発において、インフラやアプリケーションアーキテクチャをどのように構成すべきかを考える(編集部)
CGM(Consumer Generated Media)サイトを構築する際、考慮するべき点を挙げだすときりがない。
スケールアウトの容易なインフラ設計(第1回「CGMサイト構築で悩む負荷対策と拡張性の確保」参照)、開発効率の高いフレームワークの選定、保守性の高いソースコードの製造など、さまざまな要素が複雑に絡み合っている。
しかし、これらはあくまでも開発側として立った場合の視点であり、実際に利用する人々にとってはまったく関係のないことで、(当然のことではあるが)利用する人々は「触っていて快適」なサービスを求めている。
Web開発業界ではちらほらと聞かれる言葉ではあるが、Ruby on Railsはフルスタックフレームワーク故の便利さと引き換えに、パフォーマンスを犠牲にしている側面がある。
ユーザーがストレスを感じてしまっては、どんなに素晴らしい企画やアイデアであったとしてもサービスとして提供することはできない。
パフォーマンスを向上させるには?
患者さん・患者家族のためのコミュニティサイト「ライフパレット(LifePalette)」では、第1回で触れたように、拡張性とパフォーマンスを考慮したインフラ設計が行われている。
余談ではあるが、筆者自身はインフラ設計にはほとんどかかわっておらず、アプリケーション設計を主に担当していた。アプリケーションが遅ければ、せっかくのインフラアーキテクチャを台無しにしてしまう。
以下に、Railを使用する際に用いられる一般的なパフォーマンス向上方法を紹介しよう。
- O/Rマッパーを介さずに直接SQL文を発行する
→ActiveRecord::Base::find_by_sqlメソッド - 部分テンプレートキャッシング
→flagment_cache - レコード走査時に、関連先オブジェクトを一括生成する
→eager loading
しかし、これらの大部分はソースコードの記述方法に依存している。例えば、いわゆる「急ぎの作業」が発生した場合、直接SQL文を書かずに便利なO/Rマッパーに頼ってしまうことも「ありがち」な事象である(Railsは便利過ぎるのが欠点なのかもしれない)。
そういった点を踏まえると、根本的なフレームワークのパフォーマンスを向上させることが、最も安定してパフォーマンスの良いアプリケーション開発につながるのではないかと考えた。
そこで登場するのが、memcachedである。memcachedとはどのようなものなのだろうか。以下に概要を記載しよう。
memcachedは、データとオブジェクトをメモリ内にキャッシュすることでデータベースから読み出しを行う回数を減少させ、データベースを用いたWebサイトを高速化するためによく用いられる( http://ja.wikipedia.org/wiki/Memcachedより引用) |
memcachedサーバがダウンしたら……
memcachedを使用する際、最も効率的かつ、導入が容易である部分は「session管理」である。まず、session管理にmemcachedを使用する際のサーバ構成を下記に記載する。
必要最低限の構成は上記のみであり、普通にmemcachedを使用したsession管理をするならば十分な構成である。
しかしながら、上記のような構成ではmemcachedサーバがダウンしてしまうと、アプリケーション運用に支障を来してしまうことが懸念される。
そこで、以下の図のようなアーキテクチャを設計し、実装した。
この場合、memcachedサーバがダウンした場合、自動的にそれを検知し、以後はデータベースサーバのsession管理テーブルを参照するようにフレームワーク(=Rails)自体を動的に書き換えている。
このように、「いざというとき」のアーキテクチャを考案したが、実のところRailsには上記のような動的接続変更を実現する機構が備わっていない。
そのため、フレームワークの根幹部分の実装に大幅な修正を加える独自実装の拡張ライブラリの開発を行う必要があり、実稼働に耐え得るライブラリを完成させることは面白くも難しい作業であった。
今回は誌面の都合上、ソースコードについては詳細な記述を行わないが、いずれはpluginなどの形式で公開していきたいと思う。
また、session管理部分以外にも、ActiveRecordでの問い合わせ結果自体をmemcached上に格納するライブラリの開発も行った。しかし、これについてはリリース時までに安定した動作を確保することができず、やむを得ず導入を断念することとなった。
まとめ
前述のとおり、ActiveRecordの検索結果をmemcachedに格納することを、最終的に断念してしまっている。アプリケーション開発は、常に納期との戦いではあるが、まだまだパフォーマンス向上の余地があるだけに機会があれば改めて挑戦してみたい。
Railsはフルスタックなフレームワーク故のパフォーマンスの悪さがある半面、このような大胆で自由な拡張を許している「器の大きい」フレームワークなのだから。
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を紹介する。※ショートカットキー、アクセスキーの解説あり
|
|