Windows Azure上のMemcached

Steve Marxが、2つのNuGetパッケージ (WazMemcachedServerWazMemcachedClient) を公開しました。これらのパッケージによって、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パッケージをインストールすることで、コード全体を読むことが (そして、変更を加えることが) できます。

関連情報:

Advertisement

One thought on “Windows Azure上のMemcached

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s