normalian blog

Let's talk about Microsoft Azure, ASP.NET and Java!

Twitter上で、Windows Azure ストレージについてのたまったスレ

下記で語っているWindows Azureストレージの話は、次のURLでの「おすすめコンテンツ」に全て書いてある。流石Microsoftと言わざるを得ない… http://msdn.microsoft.com/ja-jp/azure/cc994380.aspx

  • まずはWindows Azure ストレージ Queueのお話だ!
    • Windows AzureストレージのQueueは、WorkerRoleとWebRoleとの通信を行う。つまり、フロントとバックでメッセージのやり取りをするのが主な用途だ!
    • Azure SDKに含まれるsampe-cs.zipに入っているThumnailが良い例だと思うが、WebRoleで画像のアップロード画面(軽い処理)を提供し、WorkerRoleでサムネイル画像を加工(重い処理)してストレージに格納している
    • フロントでは画像加工等の重い処理をせず、バックエンドで重い処理を行う場合等に使えぞ!
    • この辺りは「WebRoleとWorkerRoleがどういったアーキテクチャで出てきたか」の背景を追えば大体理解できると思われる
    • しかし、Queueと言うとMessage Driven Bean的なキューを想像する人もいると思うが、Windows Azure ストレージのキューは違うんだ!
    • Queueから取り出したメッセージが正しく処理できなかったら、Queueに戻す辺りは既存のQueueと一緒だが
    • Queueに格納したメッセージは「どういった順番でキューから取ってくるか分からない」、「同じメッセージが二度帰ってくるかもしれない」というのが大きな罠。Queueから取り出したメッセージは、削除されない限りQueue内で一時的に不可視になってるだけだったりする
  • 次はWindows Azure ストレージ、Blobについて語ってやる!
    • Blobは名前から想像する人間も多いだろうが、バイナリデータの格納を主な役割としているぜ!
    • アカウント⇒コンテナ⇒ブロブ⇒ブロックと言った階層関係を持っているが、アプリケーション開発者が意識するのはブロブまでだ!
    • 例えば、私が画廊的なアプリケーションを作成しようとした場合「アカウント(normalian)⇒コンテナ(gallery)⇒ブロブ(ファイル名)」という有様になる!語弊は多々あるが、大凡間違ってない!
    • 一回のPUTで格納できるブロブのサイズは64MBだが、ブロブの最大サイズは50GBになっている。自分で確かめた事は無いが、この辺りはNovemberバージョンになっているSDKが良しなにしてくれるはずだ!
    • そんな事よりも、Blobを扱うアプリケーション開発者にとって注意が必要なポイントは「共有ポリシー」が存在する事だ!"Private"と"Public"が存在する!!名前の通りPublicは誰でもアクセスできるが、Privateは対応するアカウントの所有者が認証したアクセスでのみブロブにアクセス可能
    • Blob内のデータを更新する場合、最終更新時刻を見て更新操作の制御を行っている。複数のユーザーが同時に更新しようとしたとしても、片方のユーザが更新した段階で別のユーザは更新できない。同時実行もこれでばっちりだ!!
  • 最後にWindows Azureストレージで一番肝になるであろうTableだ!
    • TableというとRDBを想像すると思うが、Windows AzureストレージのTableはKey-Value-Storeだ!だまされてはいけない!!
    • Tableの用途としてデータの永続化はもちろんだが、一番肝となるのはユーザのセッションデータを格納する処理だ!!
    • WindowsAzureがRoleのインスタンス数を可変にする事でスケーラビリティを提供しているのはご存知かと思うが、Sessionオブジェクトはインスタンス毎になる。それを解決出来るのがTableストレージだ!!
    • 一番肝になると思われる用途はWindowsAzure上でのSessionオブジェクトの代わりだと思われるが、Windows AzureストレージTableには特異なプロパティが複数存在する
    • RowKeyとPartitionKeyだ!!(Timestamp等のプロパティも別途有るが、ここでは含めない
    • ここで一瞬だけRDBでのテーブル設計を思い起こして欲しいのだが、テーブルにとって重要なプロパティが複数存在する事が有ると思う
    • 重要なプロパティが一つ⇒PartitionKeyのみ設定、二つ⇒PartionKey+RowKeyを設定、それ以上⇒PartionKeyに一つ目、RowKeyに複数格納("_"等でアプリ開発者が分割して入れる必要がある)
    • 上記の様に設計して欲しいのだが、その主な理由はPartionKeyがスケールアウトのカギを握っているからだ!
    • データはPartitionKeyに応じて分割され、永続化データとして格納される。PartitionKeyの設計を誤ると「クラウドだからスケールアウトするよね〜♪」と能天気に言えなくなるぞ!
    • 次にRowKeyの説明をする事をサボる事は出来ない。これもWindows Azure ストレージのTableを使う場合に避けては通れない道だ!
    • RowKeyに対する説明を一言でするなら、永続化データが格納される順番を教えるキーとでも言えば良いのだろうか
    • TableのデータはParitionKeyによって分割され、RowKeyによって辞書順に並びかえられて格納される。つまり、dataContext.Take(10)とか実装した場合に「最初の10個に何が来るか?」はRowKeyによって決定されると言う事だ!
    • 従って、PartitonKey⇒「スケールアウト用にグループ化する為に用いる」、RowKey⇒「データの並び順を制御する為に用いる」と言える!
    • 今までの流れで「別にOrderByするから良いよ」と思った人、要注意だ!Windows Azureストレージは集合関数が軒並み実装されていない!OrderBy、Single、Max、Min、Averageなんかは全滅だ!!