Steve Marxが、2つのNuGetパッケージ (WazMemcachedServer、WazMemcachedClient) を公開しました。これらのパッケージによって、Windows Azureの動的スケーリング、インプレース アップグレード、耐障害性を活用して、Windows AzureアプリケーションにMemcachedを追加することが、驚くほど簡単になります。
なぜMemcachedか?
Windows Azureは、組み込みの分散キャッシュ ソリューション (Windows Azure AppFabric Caching) を提供しています。これは、Windows Azureアプリケーションにキャッシュを簡単に追加したい.NET開発者にとって、優れた選択肢です。しかし、Memcachedを使いたいというお客様からの声を聞いています。
特にMemcached向きと思われるシナリオは、既存のRAMの再利用です。たとえば、Webロール インスタンスに使っていないRAMがある場合、Webロール インスタンスにMemcachedを追加すると、追加のVMなしで (つまり、追加コストなしで) インメモリー キャッシュを使うことができます。Windows Azure AppFabric Cachingは素晴らしい「ローカル キャッシュ」オプションを提供していますが、このオプションを使うには、リモート キャッシュがプロビジョニングされている必要があり、ローカル キャッシュは共有されない (インスタンスごとである) ことに注意しましょう。
Memcachedを選択する他の理由は、キャッシュを手動チューニングできることです。これは「気弱な人」向けではありませんが、すでに自身の特定のワークロードに対してMemcachedのチューニング (おそらく、キーごとの最小領域の変更) を行うエキスパートである人々にとっては、これは素晴らしい選択肢です。
どのように動作するか?
サーバーサイドの実装は単純で、内部エンドポイントをリスンするMemcachedを起動するだけです。クライアントサイドでは、多少の作業が行われます。クライアントには、達成したい2つの目標があります。
- サーバーの追加/削除時の中断を最小化する、コンシステント ハッシュ法を使うこと
- (スケーリング、アップグレード、障害の際の) クラスターに対するサーバーの追加/削除時に、自動的に対応すること
既定でコンシステント ハッシュ法を使う「Enyim Memcached Client」をベースにソリューションを構築することで、第1の目標は達成されます。第2の目標は、WindowsAzureServerPool
というカスタムIServerPool
実装という形で、Enyimを拡張することを意味しています。このコードは、新たに追加/削除されたWindows Azureインスタンスを定期的に探し、Memcachedクライアントを自動的に再構成します。重要なのは、このコードが、新規Windows Azureインスタンスが初めて追加されたときに、すぐにそれを使おうとはしないことです。新規インスタンスをキャッシュ サーバーとして使うおうとする前に、そのインスタンスが接続を受け入れるまで待機します。
このパッケージは、Channel 9が使っているコードをベースにしています。助けてくれたChannel 9チームのMike Sampsonに、大きく感謝します。
サーバーの設定
任意のロール (Webロール、ワーカー ロール) で、Memcachedを実行できます。高負荷の分散キャッシュでは、おそらくキャッシュ専用のワーカー ロールを作成するでしょう。しかし、多くのWebアプリケーションでは、単にWebロールにMemcachedを追加するでしょう。どちらの場合でも、Memcachedを稼働させるための3つの手順があります。
1. NuGetを使って、WazMemcachedServerパッケージをインストールします (パッケージ マネージャー コンソールから、install-package WazMemcachedServer
を実行します)。これによって、Memcachedバイナリ (Couchbaseの1.4.5 Windowsバイナリ) と、それを起動するための小さなヘルパー クラスが追加されます。
2. Memcachedがリスンするための、内部TCPエンドポイントを作成します (通常は、これを「Memcached」と命名します)。Visual StudioのUIを通して (ロールをダブル クリックし、左側の「エンドポイント」を選択して)、またはServiceDefinition.csdef
に直接追加することで、これを行います。
3. Memcachedプロセスを起動し監視するコードを、WebRole.cs
またはWorkerRole.cs
に追加します。
Process proc; public override void Run() { proc.WaitForExit(); } public override bool OnStart() { proc = WindowsAzureMemcachedHelpers.StartMemcached("Memcached", 512); return base.OnStart(); }
第1パラメーターは、手順2で作成したエンドポイント名です。第2パラメーターは、Memcachedで使いたいRAMの容量 (MB単位) です。このRun
メソッドは、Memcachedプロセスの終了を (できれば永久に) 単に待機していることに注意しましょう。これによって、Memcachedがクラッシュすると、ロール インスタンスも停止し、Windows Azureがあなたに代わってすべてを再起動してくれます。ロールのRun
メソッドで他のことを行っている場合は、代わりに、プロセスのExited
イベントを使ってプロセスのクラッシュに対応したいでしょう。
この時点で、ロールのすべてのインスタンスで、Memcachedが稼働し、内部エンドポイントをリスンしています。
クライアントの設定
コードからMemcachedサーバーのクラスターを利用するためには、スケーリングやアップグレードのためにMemcachedサーバー インスタンスが増減しても、それを見つける方法を知っているクライアントが必要です。その設定は簡単です。
1. install-package WazMemcachedClient
で、WazMemcachedClientパッケージをインストールします。これによって、設定したMemcachedサーバーを発見して使うためにEnyim Memcached Clientを拡張する、いくつかのクラスが追加されます。
2. コードで、Memcachedと対話するためにアプリケーション ライフサイクル中に再利用するMemcachedClient
を作成します。Webアプリケーションでは、ASP.NET MVCコントローラーのstatic変数に、MemcachedClient
を格納します。
static MemcachedClient client = WindowsAzureMemcachedHelpers.CreateDefaultClient ("WorkerRole", "Memcached");
第1パラメーターは、Memcachedが稼働するロール名です。第2パラメーターは、Memcachedがリスンしている内部エンドポイント名です。クライアントを初期化する素晴らしい場所としては、他にApplication_Start
があります。
Application["memcached"] = WindowsAzureMemcachedHelpers.CreateDefaultClient("WorkerRole", "Memcached");
すると、コード内のどこからでも、Application["memcached"]
を使ってクライアントにアクセスできます。
一度これら2つの手順を行うと、Memcached操作を実行するために、作成済みのMemcachedClient
を使用できます。たとえば、次の通りです。
string value = client.Get(key) as string; if (value == null) { value = FetchFromStorage(key); client.Store(StoreMode.Set, key, value); } return value;
ダウンロード
NuGetパッケージはソース コード形式なので、2つのNuGetパッケージをインストールすることで、コード全体を読むことが (そして、変更を加えることが) できます。
関連情報:
- blog.smarx.com > Memcached in Windows Azure (2011/08/29)
- http://blog.smarx.com/posts/memcached-in-windows-azure
- ブチザッキ > Memcached in Windows Azure (2011/08/30)
- http://buchizo.wordpress.com/2011/08/30/memcached-in-windows-azure/
One thought on “Windows Azure上のMemcached”