Memcachedは、非常に高速なメモリ内のオブジェクトをキャッシュするためのシステムです。 Memcachedを使用すると、最小限のコストでRailsアプリケーションの速度を大幅に向上させることができます。
前提条件
Ruby on RailsとMemcachedが既にシステムにインストールされていることを前提としています。 そうでない場合は、以下のリンクが役立ちます。
また、Memcachedを使用して最適化する予定の実行中のRailsアプリケーションがあることを前提としています。
Dalli Gemのインストール
最初に行う必要があるのは、Mike Perham
Dalli gemをインストールすることです。
gem install dalli
Bundlerを使用している場合は、
gem 'dalli'行をGemfileに追加し、
バンドルインストールを完了します。
次に、RailsとMemcachedの間の相互作用を構成するための非常に短い方法を説明します。
Railsの構成
まず、RailsとMemcachedの間の相互作用を構成するには、
config / environment / production.rbファイルを編集する必要があります。 キャッシングにDalliを使用するようにRailsに指示する次の行を追加します。
config.cache_store = :dalli_store
ActionControllerがキャッシュできるように、同じファイルに別の行を追加します。
config.action_controller.perform_caching = true
これで、通常の将来の作業のためにRailsアプリケーションを再起動するときが来ました。
Railsアプリケーションのセットアップ
Memcachedをさらに使用するには、Railsアプリケーションを構成する必要があります。 構成には主に2つの方法があり、それらについては以下で説明します。
キャッシュ管理のためのヘッダー(Cache-Control)の追加
最も簡単な方法は、ヘッダー(Cache-Control)を追加して、アクションの1つにキャッシュを制御することです。 これにより、Rack :: Cacheは、アクションの結果をMemcachedに保存できます。 この場合、
app / controllers / slow_controller.rbのアクションには次が含まれている必要があります。
def slow_action sleep 15
次の行を追加して、Rack :: Cacheが結果を5分間保存できるようにすることもできます。
def slow_action expires_in 5.minutes sleep 15
これで、このアクションを再度実行すると、作業速度が大幅に向上したことに気付くはずです。 Railsは5分ごとにアクションコードを実行して、Rack :: Cacheを更新します。
Cache-Controlヘッダーは一般公開されます。 特定のユーザーにのみ表示されるアクションがある場合は、
expires_in 5.minutes、public => falseを使用し
ます 。 また、アプリケーションに最適なキャッシュ時間を決定する必要があります。 アプリケーションごとに、この最適な時間は異なる場合があり、経験的に決定する必要があります。
HTTPキャッシングの詳細については、Mark Nottingham
のWeb AuthorおよびWebmasters向けキャッシングガイドを参照してください。
Memcachedにオブジェクトを保存する
アクションにリソースを大量に消費する操作がある場合、または何らかの理由で頻繁に作成する必要があるオブジェクトを操作する場合、中間結果をMemcachedに保存するのが合理的です。 アクションに次のコードが含まれているとします:
def slow_action slow_object = create_slow_object end
次のように、Memcachedに結果を保存できます。
def slow_action slow_object = Rails.cache.fetch(:slow_object) do create_slow_object end end
この場合、RailsはMemcachedからキー「slow_object」を持つオブジェクトを要求します。 オブジェクトが既に存在する場合(以前にメモリに保存されていた場合)、オブジェクトが返されます。 それ以外の場合、ブロックの内容が実行され、結果が「slow_object」に書き込まれます。
フラグメントキャッシング
フラグメントキャッシングは、Railsの機能の1つで、アプリケーションの最も動的な(多くの場合、変化する)部分をキャッシュできます。 ビューの任意の部分を
キャッシュブロックにラップすることで
キャッシュできます。
<%
このキャッシュ手法は、
ロシアの入れ子人形と呼ばれます。 RailsはこれらのフラグメントをすべてMemcachedにキャッシュします。 モデル名をパラメーターとして
キャッシュメソッド呼び出しに追加したため、
キャッシュ内のこれらのモデルのキーは、モデルが変更されたときにのみ変更されます。 「タスク」モデルを更新する必要がある場合、この問題は特に関連します。
@task.completed! @task.save!
したがって、ネストされたオブジェクトキャッシュがあり、Railsはモデルに関連付けられたフラグメントキャッシュの有効期間について何も知りません。 この場合、ActiveRecord
タッチキーが役立ちます。
class Employee < ActiveRecord::Base belongs_to :manager, touch: true end class Task < ActiveRecord::Base belongs_to :employee, touch: true end
タスクモデルが更新されたので、キャッシュはフラグメントに対して無効になり、
従業員モデルにはフラグメントも更新する必要があることが通知されます。 次に、
Employeeモデルは
Managerモデルに、キャッシュも更新する必要があることを伝えます。 その後、キャッシュの更新プロセスは正常に完了したと見なすことができます。
ロシアのマトリョーシカタイプに類似した別の追加のキャッシュの問題があります。新しいアプリケーションをデプロイするとき、Railsはいつビューを更新するかを知りません。 次のように「タスク」を更新したとします。
<%
部分テンプレートを使用している場合、Railsはフラグメントキャッシュを更新できません。 以前は、この問題を回避するには、
キャッシュメソッドにバージョン番号を追加する必要がありました。 現在、この問題は
cache_digests gemを使用して解決できます。これは、キャッシュキーにMD5ハッシュを自動的に追加します。 部分的なテンプレートを更新してアプリケーションを再起動すると、キャッシュキーも更新され、Railsは新しい世代のビューテンプレートを実行するように強制されます。 また、たとえば、部分的な
_incomplete_tasks.html.erbテンプレートが
変更さ
れた場合に、すべての依存テンプレートがチェーンで更新されるように、テンプレートファイル間の依存関係を処理する方法も知っています。
この機能はRails 4.0で考慮されていました。 以前のバージョンを使用している場合は、次のコマンドを使用してgemをインストールする必要があります。
gem install cache_digests
バンドラーを使用している場合は、gemfileに次の行を追加します。
gem 'cache_digests'
高度なRailsとMemcachedのカスタマイズ
Dalli gemは非常に強力なソリューションであり、Memcachedサーバーのクラスター内のキーを操作する機能を提供します。 彼は負荷を分散する方法を知っているため、Memcachedの可能性が高まります。 複数のサーバーがある場合は、各サーバーにMemcachedをインストールし、
config / environment / production.rb構成ファイルに適切な設定を追加できます。
config.cache_store = :dalli_store, 'web1.example.com', 'web2.example.com', 'web3.example.com'
この設定により、
一貫したハッシュを使用し
て 、使用可能なMemcachedサーバー間でキーを配布できます。