Google App Engineの紹介

さて今日からApp Engineの勉強を始めます。読み終えるころにはApp Engineを乗りこなせるようになってるかなぁ〜。

ランタイム環境

最初の説明はランタイム環境に関してです。たしかに公式サイトのWhat is Google App Engineを見てもこのランタイム環境の説明から入ってます。App Engine上でWebアプリケーションがどんな環境で実行されるのかがいかに重要なのかが伺えます。


App Engineのランタイム環境でもっとも重要なのは、それがSandboxであるということでしょう。つまりそれぞれのHTTPリクエストが隔離されているのです。同じアプリであったとしても別のHTTPリクエストは異なるサーバ上で実行されたりします。なので、安直に状態をグローバル変数に保持していても意味がないのです。

静的ファイルサーバ

恥ずかしながら、このようなものがあるとは知らなかったんですが (知らないうちに使っているのかも) 、静的なファイル (cssとかhtmlとかjavascriptファイルとか) はWebアプリとは別に管理することが出来るそうです。もっと静的なファイルに特化したサーバに管理させるんですって。こちらのサイトに分かりやすい説明がありました。

効率向上のため、App Engine では、静的ファイルをアプリケーション ファイルとは別に保存して処理します。このため、静的ファイルはアプリケーションのファイル システムからはアクセスできません。アプリケーション コードで読み取る必要のあるデータ ファイルの場合、そのデータ ファイルはアプリケーション ファイルにする必要があります。また、これを静的ファイルのパターンと一致させないでください。

http://code.google.com/intl/ja/appengine/docs/python/config/appconfig.html#Static_File_Handlers


なるほど、とても大事な項目なのできちんと理解する必要がありますね。

データストア

私が個人的に一番難解だと思う箇所です。そもそもデータベース自体に明るくないので当然といえば当然です。。。まぁ、ちょっとずつ慣れていきたいと思います。App Engineのデータ保存用バックエンドはデータストアと呼ばれるものです。App Engineのデータストアに関しては、まずこちらのサイトを熟読されることをおすすめします。


Googleの巨大分散データストアBigtableとDatastoreを理解する


App Engine公式サイトのDatastoreの説明を読んでもピンと来ない方であれば、なるほど〜、と頷くこと間違いなし (?) です。本書を読み進める予習にもなります。

エンティティとプロパティ

App Engineのデータストアの文章を読むとき、いつも混乱するのが用語です。RDBMSの用語とこんがらがってしまいます。↑で紹介したサイトに分かりやすい比較表があったので掲載しておきます。

RDBMS Datastore オブジェクト指向言語 (Java)
テーブル 種別 (Kind) クラス
レコード (行) エンティティ オブジェクト (インスタンス)
カラム (列) プロパティ フィールド


何となく対応関係が分かりますよね。でも決して同じものではないので誤解なきように。

クエリとインデックス

App Engineのデータストアの最大の特徴がこのクエリとインデックスの関係だと私は思います。通常インデックスというと検索の速度を上げるために準備する、いわばオプション的な役割だと思います。つまりインデックスがなくても (遅くはなってしまうけど) 検索することは出来る。ですが、App Engineの場合は違います。クエリ (データストアへの問い合わせ) とインデックスは不可分の関係です。つまりインデックスがないとクエリを発行出来ないのです。


なぜ?と思われるかもしれません。私もそうでした。でも↑で紹介した記事を見るとかなりの程度納得されると思います。その理由はBigTableにあります。簡単に説明すると、BigTableというGoogleの巨大分散データストアは単純なKey-Valueの組み合わせでしか管理されていないため、RDBMSのようなSELECTなどが出来ません。そこでApp EngineではDatastoreというサービスを間にハサミます。DatastoreサービスはBigTable上のデータを「Kind/Property名/Property値/エンティティキー」というインデックスとエンティティキーの組み合わせ (Key-Value) を列挙したインデックスを使って、クエリをインデックスのスキャンに変換することで擬似的にクエリを実現しているのです。なので、クエリはインデックスがないと発行出来ないというわけです。

indexes:

# AUTOGENERATED

# This index.yaml is automatically updated whenever the dev_appserver
# detects that a new type of query is run.  If you want to manage the
# index.yaml file manually, remove the above marker line (the line
# saying "# AUTOGENERATED").  If you want to manage some indexes
# manually, move them above the marker line.  The index.yaml file is
# automatically uploaded to the admin console when you next deploy
# your application using appcfg.py.

- kind: Greeting
  ancestor: yes
  properties:
  - name: date
    direction: desc


これはGreetingという種別 (Kind) のdateというプロパティを降順でソートした時に生成されたインデックスファイルです。個々の意味はちょっと置いておくとして、このインデックス定義を元にApp Engineはインデックスを生成して、クエリを発行するというのが分かります。

トランザクション

この内容もデータベースに明るくない私には概要を理解するだけでも一苦労。まずそもそもトランザクションとは、データベースに対する一連の操作 (たとえばデータを読み込んで、計算してその結果を使って更新する、とか) を他のユーザから邪魔されることなく実行するためのシステムです。もちろんトランザクション中、他のユーザは更新途中の情報を閲覧することはありません。トランザクションは成功するか失敗するかしかありません。中途半端な状態がない、ということです (一貫性と呼ばれるもの) 。


App Engineでは楽観的排他制御*1という方法でトランザクションを適用するか適用しないかを決めています。つまりトランザクションの最初でエンティティの更新タイムスタンプをとっておき、実際にコミットする直前で更新タイムスタンプが変わっていなければそのままコミットし、変わって入れば、他の誰かが先に更新してしまったということで再度トランザクションをやり直すのです。


なお、注意すべきはApp Engineのトランザクションでは一つのエンティティにしか操作が出来ないということです。これでは複数の種別が関連している場合、扱いにくいですよね。この時使うのがエンティティグループです。異なる種別のエンティティを一つのエンティティグループに設定しておけば、一つのトランザクションで扱えるようになります。


この辺り、しっかり理解しないとApp Engineを乗りこなすには難しいように感じます。頑張らねば!

サービス

ここではデータストアの他にも利用可能なサービスについて紹介があります。

  • メモリキャッシュ (memcache)
  • URL Fetch
  • Mail
  • XMPP
  • 画像処理

※もちろんこの他にもあります。


この中でちょっと面白いと感じたのが、Mailサービスです。こちら、当然メールを送信することが出来るのですが、なんと受信も出来るらしい。XMPPサービスのチャットメッセージも同様です。

Google Accounts

App Engineではユーザ管理にGoogle Accountを利用することが可能です。Get Startedでもサンプルに取り上げられています。


Google Appsと連携したり、Google Appsを利用しているシステムの中で開発されるシステムであれば、Google Accountを使うことに意義は (大いに) あると思いますが、Google Appsと関係のないところでGoogle Accountを使うのことは個人的にはあまり好きではありません。やっぱり独自のユーザ管理をしたい、と思ってしまいます。なお、OpenIDの利用も可能なようです。

タスクキューとcronジョブ

Pythonの学習をしている時、ちょっと記載しましたが、App Engineのアプリケーション内ではスレッドを起動することは許されていません。スレッドは全てApp Engine側で管理されているためです。ですが、HTTPリクエスト以外のタイミングで処理を実行したい時があると思います。たとえば、一日一回決まった時間にユーザにメールを出すとか。そのような時はスレッドを使うのではなく、タスクキューを使います。タスクキューはHTTPリクエスト同様、App Engine側で管理しているスレッドが、時刻を指定している場合はその時刻に、指定していない場合は任意の時刻に登録した処理 (これをタスクといいます) を実行してくれます。なお、時刻を指定したタスクのことをcronジョブといいます。

開発ツール

ここではSDKに関して記載されています。これまでApp Engineをかじって来ましたが、ほとんどツールを使って来ませんでした。デバッグ用Webサーバとアップロードツール (appcfg.py) ぐらいです。いろいろ便利なツールがあるようですね。本書の勉強を進めていく中で触って行こうと思います。

管理コンソール

App Engineにアプリケーションを登録 (Deploy) した後、アプリケーションのログを確認したり、データストアやタスクキューの状況などいろいろな動作状態を確認するのに、管理コンソールを利用することが出来ます。課金の設定もここで行います。


・・・と言いつつ、ほとんど使ったことがありません。まぁ、Hello, worldレベルのアプリしか登録したことがないのでねっ!


(私に関しては、万に一つも可能性はありませんが) もし仕事で使うようなことがあれば、この辺の情報は必須になりますね。

App Engineが (今のところ) できないこと

本書が出版された当時の状況でApp Engineで出来ないことがいろいろ書かれています。いまいちピンと来ない (もちろん私が不勉強なので) ものが多いのですが、勉強を進める中で分かってくるでしょう。今はそんなに気にせず進めます。

始めてみよう

というわけで、第一章はおしまい。最近App EngineのSDKがアップデート (1.5.3) されたので入れ替えておきます。また以前EclipseにPyDevをインストールしましたが、HTMLエディタもインストールしておきます。今回インストールしたHTMLエディタはこちら。

Eclipse HTML Editor Plugin

Amateras (アマテラス) というプロジェクトの名前に惹かれました。またついでにYAMLファイルを編集するためのプラグインもインストールしました。

yamleditor

*1:これに対し悲観的排他制御は他のユーザがトランザクション実行中はトランザクション自体を失敗させる、というもの