Google App Engine入門:Entity Groupとトランザクション処理
2009.11.09

今週に入ってから、ようやく少し本気でGoogle App Engineでプログラムを書き始めている私だが、ようやく Entity Group の使い方が分かって来たので簡単に解説してみる。
Entity Groupとは、一口で言えば「トランザクションを使ったアトミックな読み書きの対象となるEntity(=データベース上のオブジェクト)の集まり」である。
イメージとしては、まず「一つのハノイの塔を三人で同時に遊んでいる姿」を思い浮かべると分かりやすいかも知れない。全くのルールなしで皆で同時に遊ぼうとすると、腕が交錯してぐちゃぐちゃになってしまう。
そこで、「ある時点でハノイの塔ボード(三つの棒を支えている水平に置かれた板)に触ることが出来る人は常に一人。一度ボードに触った人はすべての円盤をいずれかの棒の位置に置いた状態にしてからしか手を離してはいけない。もし自分がハノイの塔に触りたい時に、すでに誰かが触っている場合にはその人の後ろに列を作って順番を待たなければいけない」というルールを定めて混乱を避ける。
App EngineのEntity Groupとはまさにそんな感じ。同じEntity Groupに属するEntityのいずれか(つまり同じハノイの塔に属する円盤のどれか)を操作する際には、db.run_in_transaction() という仕組みを使って一連の操作をAtomicに行う(つまり、ボードから手を離さずに一連の操作を行う)。一つのスレッドがトランザクションから抜ける時に(つまり、だれかがボードから手を離すときに)常にデータの整合性が取れた形になっていること(つまり、ハノイの塔のルールに従ってすべての円盤がいずれかの場所に順番に積まれている状態)を保証することにより、スレッドやマシンが何台に増えようと(プレーヤーが何人に増えようと)破綻することなくサービスを運営することが可能になるのだ。
これだけだと一般的なリレーショナル・データベースのトランザクションと違いはないが、Google App Engineの特徴は、このEntity Groupを自由な形でいくつでも作ることができる点。そして、データベースそのものが巨大になって複数のマシンにまたがってしまっても問題なくスケールする点。それぞれのEntity Groupに対してトランザクション処理ができるため、全体のスループットを落とさずに同時期に大量のトランザクション処理を行うことが可能になるのだ。
これを理解するには、1000個のハノイの塔ボードの間を3000人のプレーヤーが自由に歩き回って遊んでいる姿を想像すると良いかもしれない。一見カオス状態に見えるかもしれないが、それぞれのハノイの塔ボード上の円盤は個別のEntity Groupに属するため、先の「ある時点でハノイの塔に触ることが出来る人は常に一人。一度触った人は...」というルールはボードがいくつになろうとプレーヤーの数が何人に増えようと変わらず適用される。
この仕組みのすぐれたところは、それぞれのハノイの塔ボードに載っている円盤の数さえ同じであれば、ボードの数がどんなに増えようとそれに応じてプレーヤーの数さえ増やして行けばスループットは落ちない(つまり、リニアにスケールする)という点である。それどころか、すべてのボードが同じ会場にある必要すらなく、東京に1000個、ニューヨークに1000個、ロンドンに1000個あってもかまわない。
Google App Engine上でEntity Groupを作るには、一つGroupのルートとなるEntityを定め、他のEntityをその子孫(子供、孫、ひ孫、...)として関連づければ良い。ハノイの塔の場合だと、ボードをルートとし、その上の三本の棒と10枚の円盤をその子供と定めることに相当する。
そんな親子関係を作っておくと、それらの(同じEntity Groupに属する)Entityを実際にディスク上で近いところに格納することにより高速なトランザクション処理を可能にする、というのもApp Engineのすぐれた所だ。
なんだか言葉ばかりならべた抽象的な話になってしまったが、まずはこのあたりの「概念」からしっかりと把握した上でGoogle App Engine上のアプリを作ることをおすすめする。結局のところ、スケーラブルなウェブサービスが作れるかどうかは、Datastore上のデータ構造をどう設計するかにかかっているのだから。
とてもわかりやすい表現で理解できました!
ありがとうございました。
Posted by: masamitsu | 2009.11.10 at 04:37
> 結局のところ、スケーラブルなウェブサービスが作れるか
> どうかは、Datastore上のデータ構造をどう設計するかに
> かかっているのだから。
非常に含蓄に富んだ言葉だと思います。
性能面でトラブルの発生している事案をレスキューすると、データ構造が原因となってDBがボトルネックになっていることが多いです。
Posted by: ibushi | 2009.11.10 at 17:22