Windows Azure: Windows Azure のコスト設計
クラウド コンピューティングと Windows Azure 対応のアプリケーションとソリューションを設計するには、これまでとまったく異なる方法で運用コストを検討する必要があります。
Maarten Balliauw
IT では、クラウド コンピューティングや Windows Azure などのプラットフォームは、次なる目玉として位置付けられています。数え切れないほどあるクラウド コンピューティングのメリットを考えると、これは当然のことでしょう。
コンピューティングとストレージは、実際に使用した分に対してのみ支払いが発生し、いつでもオンデマンドで使えるものになっています。ですが、この特性により問題も発生します。クラウド アプリケーションを通常のアプリケーションと同じように設計すると、アプリケーションのコスト見通しは、予想とは異なるものになります。
さまざまな指標
従来の IT では、一連のハードウェア (ネットワーク インフラストラクチャ、サーバーなど) を購入し、セットアップと構成を行ってから、インターネットに接続していました。これは、1 回限りの投資で、必要な作業はノブとネジを回すことだけでした。
クラウド コンピューティングでは、コスト モデルが投資モデルに置き換わります。サーバーの処理能力とストレージなどのリソースについては、実際の使用量に応じて対価を支払います。Windows Azure のようなクラウド プラットフォームでは、月々の使用料の計算に次のような評価基準が使用されることが予想されます。
- 仮想マシン (VM) を保有していた時間 (現在実行されていなくても展開されたアプリケーションがあれば、その対価を支払う必要があります)
- 仮想マシンに含まれている CPU の数
- 入出力の帯域幅 (GB)
- 使用したストレージの容量 (GB)
- ストレージで実行したトランザクションの回数
- SQL Azure 上にあるデータベースのサイズ
- Windows Azure Platform AppFabric の接続数
価格の詳細については、Windows Azure の Web サイト (microsoft.com/japan/windowsazure/offers) を参照してください。この比較表からわかるように、検討事項が多数あります。
仮想マシンを制限する
ここでは、実用的な観点から、この違いを分析します。実行する VM の数を制限することはコストを削減するうえで役立ちますが、Web ロールについては、最低でも 2 つのインスタンスの VM を保持して、可用性と負荷分散を実現するのが理にかなっています。Windows Azure 診断 API を使用して、VM インスタンスの CPU の使用率、HTTP 要求の数、メモリ使用量を測定し、アプリケーションを適宜スケール ダウンします。
ロールに関係なく Windows Azure で 1 つの VM インスタンスを 1 か月にわたって使用すると、請求書に記載される時間数は 2 倍になります。たとえば、平均で 3 つのロールのインスタンスを実行している場合 (2 つの場合もあれば、4 つの場合もあります)、ワークロードがほとんどない状態で常時 4 つのインスタンスを実行している場合よりも 25% コストを削減できます。
ワーカー ロールについても、バックグラウンドで処理を行うために、最低でも 2 つのインスタンスを保持するのが理にかなっています。インスタンスが 2 つあれば、1 つのインスタンスが更新のためにダウンしていたり、ロールが再起動されていたりしても、アプリケーションの可用性を維持できます。Windows Azure に対応したツールを使用することで、特定のタスクを実行するように既定のワーカー ロールを構成できます。
たとえば、写真を共有する Web サイトを運用している場合、画像のサイズを変更するワーカー ロールと電子メールの通知を送信するワーカー ロールの 2 つが必要になるでしょう。最低でも 2 つのインスタンスを使用するという規則い従うと、4 つのワーカー ロールのインスタンスを実行することになり、請求金額はかなり高額になります。画像のサイズを変更したり、電子メールを送信したりするタスクには、それほど多くの CPU の処理能力は必要ないので、両方のタスクを実行する 2 つのワーカー ロールがあれば十分でしょう。このようにすると Windows Azure の実行にかかる月々の費用を 50% 削減できます。ワーカー ロールでは、各スレッドが固有の作業を実行するスレッド メカニズムを比較的簡単に実装できます。
Windows Azure では、4 つのサイズの VM (S、M、L、XL) を提供しています。各サイズの違いは、利用可能な CPU の数、メモリ量とローカル ストレージ、および I/O パフォーマンスです。Windows Azure を展開する前に適切な VM のサイズを検討することをお勧めします。アプリケーションの実行後にサイズを変更することはできません。
月々の使用料の明細では、使用時間が S インスタンスの時間単価に変換されています。たとえば、M インスタンスを 1 時間使用した場合は、S インスタンスを 2 時間使用した場合の料金になります。M インスタンスを 2 つ実行している場合は、720 時間 x 2 x 2 という金額が請求されます。
VM のサイズを決めるときには、このことを考慮してください。S インスタンスを使用しても、同程度の計算処理能力を実現できます。S インスタンスが 4 つある場合は、720 時間 x 4 という金額が請求されますが、これは M インスタンスを 2 つ使用した場合の価格と同じです。S インスタンスを使用すると、適宜 2 つのインスタンスにスケール ダウンして、720 時間 x 2 という請求金額にすることもできます。S インスタンスは大きいインスタンスよりも細かい単位でスケール アップ/スケール ダウンできるので、大容量の CPU、メモリ、またはストレージが必要でない場合は、S インスタンスを選択することをお勧めします。
Windows Azure サービスの使用料は、アプリケーションを展開したときから発生し、ロール インスタンスがアクティブであるかどうかは関係ありません。サービスの使用料は、Windows Azure ポータルで確認できます。ポータルには、大きな箱のイメージが表示されます。「ボックスが灰色の場合、問題はありません。ボックスが青い場合、支払の期日が来ていることになります」(Brian H. Prince さん、気の利いた言い回しをありがとうございます)。
アプリケーションをステージング サーバーまたは運用サーバーに展開して、使用後にアプリケーションを無効にした場合は、アプリケーションの展開を解除することを忘れないでください。使用していないアプリケーションの使用料を支払うのは本意ではないでしょうから。また、適宜スケール ダウンすることもお忘れなく。スケール ダウンするかどうかは、月々の運用コストに直接影響します。
使用料は時間単位で支払っているので、スケール アップとスケール ダウンを行う際には、少なくともロールを 1 時間実行することをお勧めします。ワーカー ロールでは、複数のワーカー スレッドをスピンします。このようにすると、ワーカー ロールでは、1 つのタスクだけでなく、複数のタスクを実行できるようになります。大容量の CPU、メモリ、またはストレージが必要ない場合は、S インスタンスを使用することをお勧めします。繰り返しになりますが、使用していないアプリケーションの展開は解除するようにしましょう。
帯域幅、ストレージ、およびトランザクション
帯域幅とトランザクションは、複雑な指標です。現時点では、これらを適切に測定する方法は、月々の請求書を見る以外にありません。アプリケーションの適合について参考および使用できるリアルタイムの監視機能はありません。帯域幅は、トランザクションよりは簡単に測定できます。ネットワーク経由で送信するトラフィックの量が少ないほど、コストは少なくなります。とても単純です。
複数の Windows Azure の地域にアプリケーションを展開すると、事態はさらに複雑になります。たとえば、北米地域で実行している Web ロールとヨーロッパ地域で実行しているストレージのアカウントがあるとします。この場合、Web ロールとストレージの間で行われた通信は課金対象になります。
Web ロールとストレージが同じ地域 (たとえば、どちらも北米) にある場合、Web ロールとストレージの間の通信にかかった帯域幅に対して課金されることはありません。地理的に分散しているアプリケーションを設計するときには、関連のあるサービスは同じ Windows Azure の地域にまとめることをお勧めします。
Windows Azure Content Delivery Network (CDN) を使用すると、コストを削減する別の興味深い方法を利用することができます。CDN の使用料は、BLOB ストレージと同じように測定されます (つまり、毎月、格納したデータの量 (GB) に基づいて課金されます)。CDN に対して要求を行うと、BLOB ストレージからオリジナルのコンテンツを取得して、ローカルにキャッシュします (この処理は帯域幅を消費するので課金対象となります)。
キャッシュの有効期限を短く設定しすぎると、CDN のキャッシュでは、頻繁にデータを更新する必要があるため、より多くの帯域幅を消費することになります。キャッシュの有効期限を長く設定しすぎると、Windows Azure では、長期に渡って CDN にコンテンツを格納するため、毎月格納されているデータの量 (GB) に対して課金されることになります。すべてのアプリケーションで、この点を考慮して、最適なキャッシュの有効期間を特定することをお勧めします。
Windows Azure Diagnostics Monitor でも、パフォーマンス カウンター、トレース ログ、イベント ログなどの診断データの格納に BLOB ストレージを使用します。事前に指定した間隔で、アプリケーションの診断データを書き込みます。1 分ごとにデータを書き込むとストレージのトランザクションの回数が増えて、追加のコストがかかります。15 分間隔に設定すると、ストレージのトランザクションの回数は少なくなります。ただし、この方法の欠点は、診断データが常に 15 分以上前のものになることです。
また、Windows Azure Diagnostics Monitor では、格納したデータがクリーン アップされません。自分でデータをクリーン アップしないと、古くて期限切れのデータしか格納されていないストレージに対して料金を支払うことになります。
トランザクションは、10.000 回ごとに課金されます。多いと思われるかもしれませんが、現実問題として、この回数ベースで支払う必要があります。ストレージのアカウントで実行する操作は、すべてトランザクションとしてカウントされます。BLOB コンテナーを作成する、BLOB コンテナーの内容をリストする、テーブル ストレージのテーブルにデータを格納する、キューのメッセージを確認するなどの操作は、すべてトランザクションです。たとえば、BLOB ストレージを操作するときには、まず BLOB コンテナーが存在するかどうかを確認するでしょう。存在しない場合は、コンテナーを作成してから、BLOB データを格納する必要があるからです。この処理には、少なくとも 2 回 (おそらく 3 回) のトランザクションが必要になります。
BLOB ストレージに静的なコンテンツをホストする場合にも同じことが言えます。Web サイトの 1 ページで 40 個の小さな画像をホストしている場合、そのページでは 40 回のトランザクションが必要になります。トラフィックが多いアプリケーションでは、コストがあっという間に増大します。アプリケーションの起動時に BLOB コンテナーが存在することを確認し、それ以降の操作で、その確認を省略すれば、トランザクションの回数を約 50% 削減できます。このように工夫することで、月々の使用料を抑えることが可能になります。
インデックスはコストが高い作業になることがある
SQL Azure は、興味深い製品です。非常に安価な月額使用料で 1 GB、5 GB、10 GB、20 GB、30 GB、40 GB、または 50 GB のデータベースを使用できます。最初は、5 GB の SQL Azure データベースを使用するところから始めるのが無難でしょう。ですが、そのうち 2 GB しか使用しなければ、使用料に応じて料金を支払っていることにはなりません。
場合によっては、1 つの大きな SQL Azure データベースを使用するよりも、複数の SQL Azure データベースにデータを分散した方がコスト効率が良くなることがあります。たとえば、5 GB の未使用領域がある 20 GB のデータベースの代わりに、5 GB のデータベースと 10 GB のデータベースを使用することが可能です。このように戦略的にストレージを適切に使用し、その方法がご使用のデータの種類で問題がなければ、コストを削減できます。
すべてのオブジェクトでは、ストレージを消費します。インデックスとテーブルは、多くのデータベース ストレージの容量を消費します。大きなテーブルはデータベースの容量の 10 % を消費し、いくつかのインデックスではデータベースの容量の 5% を消費することがあります。
SQL Azure の月々の使用料をデータベースのサイズで分割すると、ストレージ単位のコストを算出できます。データベースに格納されているオブジェクトについて考えてみてください。インデックス X の毎月の使用料が 50 セントで、このインデックスを使用してもパフォーマンスの向上があまり見られない場合、このインデックスは削除します。50 セントは大した金額ではありませんが、いくつかのテーブルとインデックスを削除すれば、その金額は大きくなります。これについての興味深い例が SQL Azure チームのブログ記事「The Real Cost of Index (インデックス コストの実態、英語)」(blogs.msdn.com/b/sqlazure/archive/2010/08/19/10051969.aspx)で紹介されています。
アプリケーション開発では、データベースでストアド プロシージャーを使わない傾向が高くなっています。その代わりに、オブジェクト リレーショナル マッパーを使用して、アプリケーション ロジックでデータを処理する傾向が高くなっています。
このことには何の問題もありませんが、Windows Azure と SQL Azure について考えると、興味深いことがあります。アプリケーションでデータを処理するには、Web ロールまたはワーカー ロールの追加インスタンスが必要になることがあります。このような計算処理を SQL Azure に移行すると、この状況ではロールのインスタンスを節約できます。というのも、SQL Azure では、CPU の使用率ではなくストレージの使用量に基づいて課金されるため、データベースでは CPU サイクルを無料で使用できるからです。
開発者への影響
コードを記述している開発者は、コストに対して大きな影響力を持っています。たとえば、Windows Azure でホストする ASP.NET Web サイトを作成しているときには、Windows Azure のストレージを使用するセッション ステート プロバイダーを使用してロールのインスタンス間に処理を分散できます。このプロバイダーでは、ストレージと帯域幅の使用料およびトランザクションの回数に対して課金される Windows Azure テーブル サービスにセッション データを格納しています。要求ごとにユーザーの言語を特定する次のコード スニペットについて検討してみましょう。
if (Session["culture"].ToString() == "en-US") {
// .. set to English ...
}
if (Session["culture"].ToString() == "nl-BE") {
// .. set to Dutch ...
}
特に問題ないように見えますよね。技術的には問題ありませんが、コストの観点では、次のように変更するとコストを 50 % 削減できます。
string culture = Session["culture"].ToString();
if (culture == "en-US") {
// .. set to English ...
}
if (culture == "nl-BE") {
// .. set to Dutch ...
}
どちらのコード スニペットでも、まったく同じ処理を行います。1 つ目のコード スニペットでは、セッション データを 2 回読み込みますが、2 つ目のコード スニペットでは 1 回しかセッション データを読み込みません。つまり、このようにコードを変更すると帯域幅とトランザクションのコストを 50% 削減できます。キューについても同じことが言えます。1 度にメッセージを 1 通ずつ読み込む処理を 20 回行うと、1 度に 20 通のメッセージを読み込む処理よりもコストが高くなります。
ご覧のとおり、クラウド コンピューティングは、アプリケーションをホストする場合に、これまでとは異なる経済的側面と価格をもたらします。クラウド コンピューティングは、従来のデータセンターと比較して、運用コストの面では大きな改善が見込まれますが、クラウド対応のアプリケーションのアーキテクチャを設計する際には、いくつかの考慮事項に留意する必要があります。
Maarten Balliauw は、ベルギー国内の大手 ICT 企業である RealDolmen で Web テクノロジに関する技術コンサルタントとして働いています。彼が興味を持っている分野は、ASP.NET MVC、PHP、および Windows Azure です。ASP.NET MVP で、MSDN マガジン、Belgium Magazine、PHP Architect など、PHP と .NET を取り上げる雑誌などで多くの記事を公開しています。また、ベルギー国内および海外で開催されるイベントで頻繁に講演を行っています。彼のブログは、blog.maartenballiauw.be (英語) で公開されています。