Programming the Cloud -the Internet as Platform-

イケメンGregor Horhpeによるクラウドセッション。この人は、Martin Fowler SignitureのEnterprise Integration Patternsの著者の一人でもある。今回はEIPではなく、BASE〜CAP Theorem〜Google App Engineといったあたりのお話。

クラウドの良い点、悪い点
アーキテクト(の関心事)にとっては、夢を実現するコンセプト。
  • 疎結合
  • 拡張性
  • 標準への準拠
  • 耐障害性
  • 無制限のコンピューティングパワー
  • ユビキタス
しかし、開発者にとっては悪夢の発現。
  • No Call Stack
  • No Transaction
  • No Promises
  • No Certainty
  • No Ordering Constraint
# No Certaintyがよくわからず、訳せなかったので全部英語 ^^;

[メモ]
このあたりは、パネルディスカッションでGregorが話していた、ランタイムを考慮したテストの重要性が増すだろう、という話と対応しているようだ。
(ACID)Transactionがない点は、システム特性や方針レベルでは(CAP TheoremやBASEモデルとして)わりと整理されてきているんだろうけど、アプリケーションレベルでの対応方法は別の課題として(少なくともしばらくは)残ることになりそうだ。この話は、少し後にスタバの例つきで出てくる。
順序性の保証がない点は、同じくプログラミングモデルの変革に関わる部分。この話も最後あたりにStatelessとStatefulの分離の話と絡めて出てくる。

ACIDコンセプトの移り変わり
以前のACID
  • Atomic
  • Consistent
  • Isolated
  • Durable
以前のACIDに合うように作ってみた、今日のACID
  • Associative(結合性)
  • Commutative(交換可能性)
  • Idempotent(羃等性)
  • Distributed(分散)
[メモ]
結合性や交換可能性は、並列化をすすめる上で非常に重要になってくる。関数型パラダイムにも通じる概念(ですよね?)。分散は並列化のために必要になってくるのだが、分散をすすめるとノード故障への対応が難しくなってくる。この際に効率よく回復するために、計算の羃等性が重要になってくる。計算が羃等であれば、同じメッセージを再送信するだけで回復できるからだ。

分散システムにおけるトランザクション
分散システムにおいて、特定のノードと通信できなかった場合、どうするか?2フェーズコミットが必要か?スターバックスを例に考えてみよう。

結論から言うと、スターバックスは2PCをやっていない。つまり、注文を受けてからコーヒーを作り、清算して、これらすべてを1トランザクションに…というような仕事のやり方をしていない。スループットを出すために、注文を受け付けたら、清算前にコーヒーを作り始めたりしている。
さて、この一連の流れで以下のようなマズいことが起きたらどうすればいいだろう?
  • この飲み物は嫌だと、顧客に却下/返品される
  • コーヒーメーカーが壊れる
  • 顧客が支払えないことに気づく
顧客に却下された場合には、飲み物を作り直す(Retry)。コーヒーメーカーが壊れてコーヒーが提供できない場合、代金を払い戻す(Compensation)。顧客が支払えなかった場合、飲み物を捨てる(Write-off)。
このように、最初から完全を求めるのではなく、事後的に対処することで最終的な一貫性を保つようなやり方は、スタバだけでなく銀行のようなシステムにも当てはめることができる。例えば、日銀とバンク・オブ・アメリカが決済をするような場合、エントリを互いに送信しあう際には完全性を求めず、どこかのタイミングで突き合わせをすることで、エントリ送信の誤りを修正するようなことをしている。
# らしい。もちろん、本当かどうかは知らない。
ちなみに、このWrite-offというオプションは、システム開発でも特に忘れられがちな事後対処のオプションなので、もっと考えてもいいんじゃないか、というようなことも言っていた。

Googleの並列化への取り組み

みたいなタイトルで、MapReduceとかGFSとかBigTableとかの話が続いた。このあたりは有名な話ばっかりだったのでメモってない。Sawzallだけ知らなかったんだけど、これらのインフラを効率よく使うためのDSLらしい。

並列性を高めるための方法
いかにStatefulな部分をStatelessな部分から切り離すか、が重要。
例として、ファイル読み込みのようなものを考えてみる。ファイルを先頭から順に読み、一行ずつ処理していく場合、処理は何行まで進んでいるかの情報を利用可能で、処理のたびに位置情報が更新されていく形になるため、状態を持つことになる。これは、処理が位置情報を利用できるという意味で、Listに対する処理と考えても良い。
ここで、状態を持っている部分(ファイル読み込みの部分)をインフラ(ここではMapReduceだろうが)にまかせ、処理の部分はListではなくSet(集合は順序持っていないので)に対する処理とすることで、Statefulな部分とStatelessな部分を切り離すことができる。

こうすることで、Statelessな部分は並列実行できるようになる。しかし、Statefulな部分をデータ処理と切り離したことで、できないことが増えることには自覚的になる必要があるだろう。例えば、データ処理が状態を持っていれば可能な、連続して同じデータ内容の行を読み込んだ場合に誤入力としてスキップするようなことはできなくなってしまう。どんな妥協をしたのかを自覚しておくのは非常に重要。

Google App Engineのデモ
Java版の紹介とデモ。Hello, 東京!デモってやっぱり楽しいね。

雑感
拍手とともに終了。Gregorさんは話すのが好きなのか、セッションも楽しかった。
ホスト「それではいつものように、よかったと思った人は緑、まぁまぁかな、という人は黄色、いまいちかな、という人は赤を入れて...」
Gregor「Green!」
会場「ハハハハハ!」

内容的には、丸山先生の話のGoogle版といった感じかな。スタバの例がすごくわかりやすかった。自分が見たセッションで、唯一デモがあったセッションでもある。緑入れときました。

目次:
QCon Tokyo 2009に行ってきた

コメント