Rails3からmemcachedを利用する

Rails3では、構成要素のモジュール化が進み、標準のライブラリ以外は個別にインストールする方針になりました。memcachedクライアントの実装も、インストール直後の状態では含まれていないので、自分でインストールする必要があります。

一方で、ライブラリの選択がとても容易にできることは、モジュール化の恩恵と言えるでしょう。
今回は、Rails3で利用できるmemcachedクライアントとして、memcache-client と Dalli を紹介します。両者の違いは設定手順だけで、利用方法は同じです。

memcache-clientを使う

http://github.com/mperham/memcache-client

Rails2時代と同様、memcache-client を利用することができます。Gemfileに以下の行を追加して、bundle install すればインストール完了です。

gem 'memcache-client'

■キャッシュストアに設定

production環境で使用する場合は、config/environments/production.rb に次の行を追加します。接続先を指定しなければ、localhost:11211のmemcachedに接続します。

config.cache_store = :mem_cache_store

次のように、複数の接続先やオプションを指定することもできます。

config.cache_store = :mem_cache_store, 'cache-1.example.com', 'cache-2.example.com', {:namespace => NAME_OF_RAILS_APP}

■セッションストアに設定

セッションストアをデフォルトのCookieStoreから変更することもできます(あまり機会はないかもしれませんが..)。変更するには、config/initializers/session_store.rb に以下の行を追加します.

Railsアプリ名::Application.config.session_store :mem_cache_store
Railsアプリ名::Application.config.session_options = {:cookie_only => false}

こちらもキャッシュストアと同様、細かく設定することができます。

Dalliを使う

http://github.com/mperham/dalli

Dalli は、高速なpure Rubyのmemcachedクライアントです。memcached 1.4+に対応していて、バイナリプロトコルを使用しています。
開発者は、memcache-clientのメンテナンスもしている Mike Perham さんです。「記憶の固執(The Persistence of Memory)」を描いたサルバトール・ダリにちなんだ名前だとのことです。

Dalli – memcached for Ruby

Dalli には以下の特徴があります。

  • memcache-client と互換性があるので、そのまま入れ替えできる
  • Ruby 1.9.2 では約20%高速
  • モニタリングツール用にフックを提供
  • Railsに対応
  • memcache-clientの1250行から、700行にまでダイエット
  • SASLサポート

こちらもインストールは簡単です。Gemfile に下記の行を追加して、bundle install してください。

gem 'dalli'

■キャッシュストアに設定

production環境で使用する場合は、config/environments/production.rb に次の行を追加します。何も指定しなければ、localhost:11211 のmemcachedに接続します。

config.cache_store = :dalli_store

以下のように、こってりした設定をすることも可能です。

config.cache_store = :dalli_store, 'cache-1.example.com', 'cache-2.example.com', {:namespace => NAME_OF_RAILS_APP, :expires_in => 3600, :compress => true, :compress_threshold => 64*1024}

Passenger で使う場合は、config/environment.rb に設定を追加する必要があるようです。詳しくは、http://github.com/mperham/dalli を参照してください。

■セッションストアに設定

config/initializers/session_store.rb に以下の行を追加します.

require 'action_dispatch/middleware/session/dalli_store'
Railsアプリ名::Application.config.session_store :dalli_store
Railsアプリ名::Application.config.session_options = {:cookie_only => false}

試してみる

コンソールから実験してみましょう。
ここからは、memcache-client でも Dalli でも大きな違いはないので、Dalli を使った場合の結果で説明します。

$ RAILS_ENV=production rails server
> Rails.cache
 => #<ActiveSupport::Cache::DalliStore:0x000001020ce600 @options={}, @data=#<Dalli::Client:0x000001020ce0b0 @servers=["localhost:11211"], @options={}>, @thread_local_key=:active_support_cache_dalli_store_local_cache_2164683520, @middleware=ActiveSupport::Cache::Strategy::LocalCache>

キャッシュストアが DalliStore になっていることがわかりますね。

> Rails.cache.write("test", {:message => 'Hello', :time => Time.now})
 => true
> Rails.cache.read("test")
 => {:message=>"Hello", :time=>2010-09-15 13:26:09 +0900}

無事データをmemcacheにキャッシュし、その後取り出すことができました!

終わりに

memcached のアスキープロトコルには、memcached injection による攻撃を受けやすいという弱点があります。memcached injection への対策の一つは、memcached のバイナリプロトコルを使用することです。
Dalli はバイナリプロトコルを使用しているので、セキュリティの面でも優れています。Rails で memcached を使用する場合、クライアントライブラリとして Dalli を選択するのがよさそうですね。