Part 2. Windows Azure Platform 概要 その3


その 2 のエントリからの続きです。(エントリが長すぎてポストできなかったため、分割しています。)

[③ Windows Azure ストレージサービス]

Windows Azure ストレージサービスとは、大規模・大容量の、高信頼性データストレージサービスです。内部的には、データを複数のサーバで分散・冗長化して保持するようになっているのですが、外から見た場合にはこれが巨大な一つのストレージシステムに見えるようになっている、というのが、この Windows Azure ストレージサービスです。SQL Azure データベースサービスと同様、実際のデータは少なくとも 3 つのノードに複製格納されているため、ひとつのサーバがクラッシュしても、データは生き残ることが可能になっています。

※ (注意) ”Windows Azure” という名を冠していますが、前述の Windows Azure コンピュートサービスとは全くの別物なので注意してください。

※ (参考) 現状では、Windows Azure ストレージサービス、SQL Azure データベースサービスのいずれも、Geo-Replication (データセンタまたがりのデータ複製)には対応していません。

image

通常、こうしたストレージシステムに対しては、ローカル HDD であれば普通の Windows エクスプローラで、リモート HDD であればファイル共有を通してアクセスすることになります。しかし、この Windows Azure ストレージサービスでは、HTTP REST プロトコルと呼ばれる、特殊な HTTP プロトコルでデータの読み書きを行います

この HTTP REST プロトコルを直接ハンドリングするのは大変ですが、幸い、C# や VB などでアプリケーションを開発する場合には、Windows Azure ストレージサービスへアクセスするためのライブラリを使うことができます。このため、このライブラリを利用すれば、HTTP REST プロトコルを知らなくても、Windows Azure ストレージサービスへのデータの読み書きを実施することができます。例えば、コンソールアプリケーションから、Windows Azure ストレージサービスを読み書きするには、以下のようなコードを利用します。(※ このサンプルコードは特に理解しなくても大丈夫です。興味がある方は読んでください。本論からは逸れるため、今回はコードの詳細は説明しません。)

   1: CloudStorageAccount storageAccount = new CloudStorageAccount(
   2:     new StorageCredentialsAccountAndKey("nakama000", 
   3:     "sLyGGvOHJszS9wABrog4HhrxN+8ICH0A/diyMp.....JS/6Cm4S9c3TDH+CRRo8Tj5vIpgYfB7yArq1+xWjDSg=="),
   4:     new Uri("http://nakama000.blob.core.windows.net"),
   5:     new Uri("http://nakama000.queue.core.windows.net"),
   6:     new Uri("http://nakama000.table.core.windows.net"));
   7:  
   8: CloudTableClient tableClient = storageAccount.CreateCloudTableClient();
   9: CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
  10: CloudQueueClient queueClient = storageAccount.CreateCloudQueueClient();
  11:  
  12: // コンテナへの接続
  13: CloudBlobContainer blobContainer = blobClient.GetContainerReference("pictures");
  14: // コンテナの作成
  15: bool created = blobContainer.CreateIfNotExist();
  16: Console.WriteLine((created ? "コンテナを作成しました。" : "コンテナはすでに存在します。"));
  17: // コンテナに対して、public アクセスを認めるように設定(http://.../Container/BlobName でアクセス可に)
  18: var permissions = blobContainer.GetPermissions();
  19: permissions.PublicAccess = BlobContainerPublicAccessType.Container;
  20: blobContainer.SetPermissions(permissions);
  21: Console.WriteLine("権限設定しました。");
  22:  
  23: // ファイルのアップロード
  24: string path = @"C:\Users\Public\Pictures\Sample Pictures";
  25: foreach (string fullPathFilename in Directory.GetFiles(path, "*.jpg"))
  26: {
  27:     string filename = fullPathFilename.Substring(fullPathFilename.LastIndexOf("\\") + 1);
  28:     byte[] data = File.ReadAllBytes(fullPathFilename);
  29:  
  30:     // まずファイルポインタを作成
  31:     CloudBlob blob = blobContainer.GetBlobReference(filename);
  32:     // すでに存在していたら削除
  33:     bool delete = blob.DeleteIfExists();
  34:     if (delete) Console.WriteLine("すでにデータがあったため、いったん削除しました。");
  35:     // そこに書き込みを行う ※ アップロード時にエラーがあってもちゃんと報告してくれないので注意
  36:     blob.UploadByteArray(data);
  37:     // クライアントに送り返すヘッダー情報を設定
  38:     blob.Properties.ContentType = "image/jpeg";
  39:     blob.SetProperties();
  40:     // サーバ側で保持するファイルのメタデータを記録
  41:     blob.Metadata["OriginalFilename"] = fullPathFilename;
  42:     blob.SetMetadata();
  43:     Console.WriteLine("ファイルを書きこみました。" + filename);
  44: }
  45:  
  46: // ファイルの一覧
  47: var blobs = blobContainer.ListBlobs();
  48: int i = 0;
  49: foreach (var b in blobs)
  50: {
  51:     // 各ファイルのメタデータを取得
  52:     CloudBlob cb = blobContainer.GetBlobReference(b.Uri.AbsoluteUri);
  53:  
  54:     // 属性データをサーバから取得
  55:     cb.FetchAttributes();
  56:     Console.WriteLine("{0} {1} {2}", 
  57:     cb.Uri.AbsoluteUri, 
  58:     cb.Properties.LastModifiedUtc, 
  59:     cb.Attributes.Metadata["OriginalFilename"]);
  60:  
  61:     // データの読み取り(直接ファイルにダウンロードすることも可能)
  62:     cb.DownloadToFile(@"C:\temp\" + (i++).ToString() + ".jpg");
  63: }

前述した Windows Azure コンピュートサービスを利用する場合、この Windows Azure ストレージサービスは、ログデータの転送先として非常に重要なものになります。これは以下のような理由によります。

Windows Azure コンピュートサービスを利用する場合、各仮想マシンは、インスタンス数の増減やサービスのフェイルオーバなどによって、簡単に起動したりシャットダウンさせたりすることができます(というより、それが Windows Azure コンピュートサービスの大きなウリです)。この結果、ローカルマシンに記録した内容(イベントログやパフォーマンスログ、ローカル HDD 上に記録したデータなど)は簡単に消え去ったり初期化されたりすることになります。このため、Windows Azure コンピュートサービスでは、基本的にはローカルマシンやローカルリソース(例えばローカル HDD など)にデータを記録・保存すべきではありません。……が、これではログファイルなどの記録や保存を行うことが全くできなくなってしまうため、困ってしまいます。

このため、各種のデータを残しておく目的で、以下の 2 つのストレージシステムを使います。

  • SQL Azure データベースサービス : 主にトランザクショナルな業務データの保存に利用
  • Windows Azure ストレージサービス : 主に各種のログファイルの保存に利用

このようにしていただければ、Windows Azure コンピュートサービスの仮想マシンインスタンスが増減したとしても、業務データやログデータが消失することはありません。

image

とはいえ、正直なところ、各種のログデータの出力先をすべて Windows Azure ストレージサービスにするようにアプリケーションを作ったり書き換えたりするのはなかなか大変です。この問題についても以下のような対処方法が用意されています。

応用的な内容になるため今回の一連のエントリでは解説しませんが、Windows Azure コンピュートサービス内の各仮想マシンには、Diagnostic Monitor ランタイムと呼ばれるサービスがインストールされています。このサービスは、イベントログやパフォーマンスログ、フラットファイルなどを定期的に監視・データ収集し、Windows Azure ストレージサービスへとデータを転送するようになっています。このサービスが存在するため、各アプリケーションから直接 Windows Azure ストレージサービスへデータを書き込む必要はなく、従来通り、イベントログやパフォーマンスログなどにデータを出力しているだけで済むようになっています

image

ただし、既定ではこれらのサービスは動作していません。このため、構成設定や起動処理を行うことによって、このデータ転送機能を有効化する必要があります。Diagnostics Monitor が既定で転送できるデータの種類は以下の通りです。(転送処理を自力で作り込むこともできるようになっています)

image

※ (参考) Diagnostic Monitor ランタイムの使い方についてはここでは紹介しませんが、このサイトが非常に詳しいので、興味がある方は読んでみてくださ���。(おそらく Diagnostic Monitor ランタイムを作っているチームの人だと思います)

※ (参考) なお、残念ながら現時点では Windows Azure ストレージサービスに転送されたログデータを簡単に見る方法(ビュアー)が提供されていないため、それらについては自作する必要があります。というか RTM したらログビュアーが提供される、という話だったような気がするんですがまだ提供されていないような……;

※ (注意) Diagnostic Monitor ランタイムによるログデータの転送機能は、遅延転送での動作になっています。このため、仮想マシンのクラッシュが発生した場合には、ログのとりこぼしが発生する危険性があります(通常の Web サーバでもマシンがクラッシュした際にはデータロストが発生するので当たり前のことですが;)。欠損してはならないデータの場合には、このログ転送の仕組みを使うのではなく、業務ログとして、SQL Azure データベースサービスなどに書き込むように設計してください

さて、Windows Azure ストレージサービスでは、予め 4 種類のデータ構造が定義されており、それぞれの構造を持つデータを簡単に出し入れすることができるように設計されています。

  • BLOB (巨大なバイナリデータ) : メディアファイルなどの格納に最適
  • Table (ハッシュテーブル的なデータ) : キー付きのデータの保存に最適
  • Queue (メッセージキュー) : Azure サーバ間の通信に利用
  • Drive (NTFS ドライブ) : あたかも NTFS ドライブのように扱えるストレージ

これらについては比較的誤解があったり、わかりにくい資料も多いため、どんなものなのかを簡単に解説しておきたいと思います。

A. BLOB (巨大なバイナリデータ)

.wmv, .wav, .mp3, .jpg, .zip, .vhd などなど、主にマルチメディア系のファイルや巨大なデータファイルなどを格納するのに適したストレージ形式です。IIS ログファイルのようなただのテキストファイルに関してももちろん保存可能で、外から見た場合には 1 階層のファイルシステムであるかのように取り扱うことが可能です。

通常の Web サーバの場合には、FTP プロトコルでファイルをアップロードすることが多いと思いますが、この Windows Azure BLOB ストレージの場合には、HTTP REST プロトコルでファイルをアップロードすることになります。以下に概念図を示します。

image

なお、重要なポイントとして、各フォルダには public / private の設定を行うことができ、public 設定にした場合には、読み取りに関しては通常の HTTP-GET によるデータ取得ができるようになっています。(ファイル書き込みに関しては、HTTP-REST プロトコルでしか行うことができません。)

※ (参考) アクセス権限設定については、public / private の 2 択で、細かいアクセス可否設定はできません。残念;。

B. Table (ハッシュテーブル的なデータ)

Table ストレージは、プレインオブジェクト(POCO、プロパティ値のみを持つようなオブジェクト)を、お皿のようなものに入れて分散格納することができるストレージです。下図のようなイメージでとらえていただくとわかりやすいでしょう。

image

Windows Azure Table ストレージを利用するためには、各オブジェクトに対して、必ず以下の 2 つのキーを付与する必要があります。(正確にはこの 2 つに加えてデータ更新時の楽観同時実行制御用の Timestamp フィールドも必要になるのですが、まあとりあえずそれは置いておくとすると。)

  • PartitionKey : データを複数のグループに分割するためのキー
  • RowKey : 当該パーティションの中での一意識別キー

同一の PartitionKey を持つオブジェクトは必ず同一ノード(同一物理サーバ)で保持されるようになっていますが、異なる PartitionKey を持つオブジェクトは別ノードに保持されます。このため、データ検索処理を行うと、下図のように、複数のノードで分散検索処理が行われるようになります。

image

このことからもわかるように、Windows Azure Table ストレージを利用する場合には、PartitionKey の設計が極めて重要になります。うかつな PartitionKey を利用すると、検索速度などが極端に劣化することがあるため、注意してください。

なお、Windows Azure Table ストレージは、「テーブル」という名前がついているものの、いわゆる RDBMS のテーブルとは全くといっていいほど異なるものです。確かに、オブジェクトインスタンスを「行」、プロパティを「列」と捉えれば、確かにテーブル的な構造を持っているといえなくもありません。

image

しかし、以下のような点は全く異なります。

  • テーブル間にリレーションシップを定義できない
  • Join 処理も不可(単独テーブルへの出し入れのみ)
  • トランザクション処理が基本的に不可(一連のデータの読み書きを 1 トランザクションに束ねることができない)
  • 任意の列にインデックスを付与することができない
  • 1 つのテーブルに、異なる構造のオブジェクトを格納できる

中でも最後の特徴は極めて重要です。Windows Azure Table ストレージでは、ストレージに対してスキーマの指定ができません。これは、Azure Table ストレージでは、(RowKey さえ異なれば)同一のテーブルに異なる構造を持ったオブジェクトを格納することができるためです。例えば、Author オブジェクトと Title オブジェクトという、異なる構造を持ったデータを同一テーブルに格納した場合を以下に示します。

image

この様子を無理矢理に表形式に書き直すと「穴空き表」になりますが、ストレージ内部で隙間だらけのデータとして格納しているわけではありません。実際には、左の図のように、「異なるオブジェクトがひとつのお皿の上に乗っているだけ」という状態になります。このような状態は、RDBMS のテーブルでは考え難いことですが、Windows Azure Table ストレージではごく当たり前のこととして扱われます。「テーブル」という名前にあまり惑わされないようにしていただければと思います。

C. Queue (メッセージキュー)

Windows Azure Queue ストレージは、その名の通り、メッセージキューシステムになります。以下のようなシンプルな機能を持ったメッセージキューシステムを提供します。

  • やり取りできるデータ → string 型と byte[] 型のみ
  • 送達保障・順序制御 → Exactly-Once のみ、In-Order なし
  • リトライキュー・デッドキュー → なし
  • メッセージ暗号化 → なし(キューに対する接続時の認証のみ)

機能は限定的ですが、その分、プログラミングは非常に単純です。

image

この Windows Azure Queue ストレージは、現在では利用シナリオが非常に限定的です。これは次のような理由によります。

  • もともと Queue ストレージは、Windows Azure コンピュートサービスにおいて、Web Role サーバと Worker Role サーバを連携させるための通信経路として使うことを念頭において設計されていた。
  • ところが現在では、Worker Role サーバが TCP/IP 通信を直接受け付けることができるようになっている。このため、Web Role サーバから Worker Role サーバへの単純な通信は、TCP/IP 直接通信で行えば済む。 (=一般的に非同期接続は設計・実装が大変になるので、わざわざ Queue ストレージを使って非同期接続する必要性はない)

image

すなわち、Windows Azure Queue ストレージを利用するのは、Web Role サーバと Worker Role サーバ間をキュー型接続(=非同期接続)しなければならない場合に限られる、ということになります(と書くとやや言いすぎですが、とりあえずはそう理解しておいても差し支えないでしょう)。実際にはそのようなケースはほとんどない(キュー型トランザクション処理が求められるケースは少ない)でしょうから、簡単なアプリケーションやシステムではほとんど使われることがない、と思っていただいてよいと思います。

D. Drive (NTFS ドライブ)

これは、中身としては Windows Azure BLOB ストレージなのですが、それをあたかも NTFS ドライブであるかのようにして使うことができる、という特殊な形式になります。アプリケーションから見た場合にはただの NTFS ボリュームであるかのように見えるため、通常のファイル I/O の API を使ってアクセスすることができる(ただし通常のローカル HDD に比べると若干アクセスが遅い)というものになります。現時点ではまだ未リリースのため詳細は不明ですが、今後、明らかになってくることでしょう。

というわけで、4 種類のWindows Azure ストレージサービスについて概要を解説してきましたが、重要なのは、どのようなケースでどのストレージサービスを使うのか、という点です。それぞれに適切な使い分けが必要になりますので、よく覚えておいていただければと思います。

[開発上の注意点]

さて、ここまで Windows Azure Platform の提供する主要サービスの概要を解説してきたわけですが、Windows Azure Platform の大きなメリットは、なんといっても

  • オンプレミス型の Web アプリケーションの開発と、ほとんど同じ技術を使うことができる。

    (Web アプリ → ASP.NET で開発、DB サーバ → SQL Server で開発)

という点でしょう。しかしこのことは、オンプレミス型の Web アプリケーションをそのまま Azure プラットフォーム上に移植できるということではありませんし、Azure プラットフォーム上での開発を、���ンプレミス型の Web アプリケーションと完全に同じように捉えられる、ということでもありません。やはり、それ相応に相違点や注意点があります。

基本的に、Windows Azure Platform は PaaS プラットフォームです。このため、オンプレミス型の開発と異なり、ハード/ミドルなどのインフラに関わる設定や運用をほとんど考えなくて済むという利点があります。半面、Web サーバや DB サーバの設定やバージョンを自由に決められない・変更できないという注意点もあります。メリットとデメリットを比較する形で書くと、以下のようになります。

  • 主なメリット

    セキュリティパッチの適用、ハード障害時の対応、SQL Server や IIS の構成設定などを考えなくて済む。(すべてデータセンタ側にお任せすることができる)
  • 主なデメリット(利用上の注意点)

    タイムゾーン設定、言語設定、照合順序(並び順)、IIS や .NET の構成設定などが変更できないことが多い。ミドルウェアやパッケージ製品の追加インストールにも制限があり、配置するアプリケーションそのものにも制限事項がある。

主だった注意点を以下にまとめます。中でも、特に日本語まわりの注意点は、日本ローカルでアプリケーションを開発していたときとは大きく異なる部分になります。十分に注意して取り組むようにしてください。

image

このため、実際に Windows Azure Platform 上で動作するアプリケーションを開発する場合には、Azure のインフラ特性などをきちんと理解し、Windows Azure Platform の特性に併せた形でアプリケーション開発を行う必要があります。以上のような背景を考えると、Azure プラットフォームに適したアプリケーションと、適していないアプリケーションとがあると言えます。具体的には以下のようになります。

Windows Azure Platform に適したアプリケーション(クラウド化が適しているもの)

  • 一般的なインターネットアプリケーション
  • トラフィックが、時期、曜日、時間帯などにより大きく変動するアプリケーション
  • ASP サービスとして展開しているアプリケーション
  • 自社でインフラを持たないソフトウェア会社が開発するアプリケーション

Windows Azure Platform に不向きなアプリケーション(オンプレミス型が適しているもの)

  • セキュリティポリシー上、社外に持ち出すことのできないデータを取り扱っているアプリケーション
  • Windows Azure Platform の SLA (サービスレベル)では不十分なミッションクリティカルシステム
  • SP や QFE などのソフトウェアバージョンを固定したいアプリケーション

Windows Azure Platform は、一般的な PaaS サービスに比べると敷居が低く、またハイブリッド型(オンプレミスとクラウドを併用する形態)などを取りやすいといったメリットがあります。しかし、あらゆるアプリケーションが Windows Azure Platform 上での動作に適しているというわけではありません。適切なシステム及び適切な部分に対して、上手にWindows Azure Platform を適用するようにしてください。

[本エントリのまとめ]

というわけで、本エントリをまとめる目的で、もう一度、Windows Azure Platform の主要構成要素を俯瞰図的にまとめておきたいと思います。

  • ① Windows Azure コンピュートサービス

    Web Role サーバ : IIS と .NET Framework がインストールされた Web サーバ

    Worker Role サーバ : .NET Framework がインストールされた汎用サーバ

  • ② SQL Azure データベースサービス

    10GB の容量制限を持つデータベース、主に業務データを保存する

    カスタムレプリケーションによる 3 多重化により 99.9% の高可用性を保障してくれる

  • ③ Windows Azure ストレージサービス

    主にログデータやバイナリデータを保存するためのストレージシステム

    A. BLOB (巨大なバイナリデータ) : メディアファイルなどの格納に最適

    B. Table (ハッシュテーブル的なデータ) : キー付きのデータの保存に最適

    C. Queue (メッセージキュー) : Azure サーバ間の通信に利用

    D. Drive (NTFS ドライブ) : あたかも NTFS ドライブのように扱えるストレージ

また、これらを利用した典型的な Web-DB アプリケーションの構成は、下図のようになります(コンピュートサービスは主に Web Role サーバを利用、ストレージサービスは主に BLOB, Table を利用)。

image

また、Windows Azure Platform は PaaS 型プラットフォームであるが故に、オンプレミス型と比べて、ランタイムやミドルウェアの設定を自由に変更できないという問題点があります。このため、ASP.NET Web アプリケーションであれば、どのようなアプリケーションでも Windows Azure Platform 上に移植できる、というわけでもありません。Part 3. のエントリでは実装の詳細に触れていきたいと思いますが、「なんでもかんでもクラウド化」といった考え方をしないように、十分注意してください。


Comments (1)

  1. yukio_saitoh より:

    この内容の更新は行われますか?行われるのであれば PDF や XPS での公開もお願いいたします。

Skip to main content