/home/by-natures/dev*

データ界隈で働くエンジニアとしての技術的なメモと、たまに普通の日記。

GoogleAppEngine ことはじめ

社内で GoogleAppEngine を使って、とある社内施策を運用しているので、簡単に特徴などをご紹介します。

[toc]

GoogleAppEngine とは?

Google のインフラ上で動かせる PaaS

PaaS(= Platform as a Service)ということで、Heroku などと同じような立ち位置ですね。

2008年に登場し、今なお様々な改訂が加えられながらサービス提供されています。

Python, Java, PHP, Go で記述可能

そんな GAE ですが、かなり使い方が限定されています。

まずは動作言語に指定があること。2013年に PHP が加わったので、Python, Java, PHP, Go の4つが開発言語となります。ただ、今のところ書籍や情報量の多さ、実用的な観点からすると Python, Java の2択になりそうです。

データベースは BigTable

次に、データベースが BigTable という KVS であること。

特に BigTable を扱う GQL という SQL ライクな言語が、SELECT しかできず、JOIN, 集合関数, 部分一致, OR, != が使えないなど、制約も多いです。つまりは純粋なフィルタのみしか扱えない、ということなのですが。

トランザクション単位も小さく、エンティティグループという単位でしかトランザクションが行えません。トランザクションを扱いたい場合はテーブル設計の段階からこの問題について認識しておく必要があります。

また、クエリ時間がデータ量にほとんど依存しないのは大きなメリットです。GFS 上で MapReduce を実行しているらしく、GQL の制約もあって非常に高速にクエリを実行してくれます。

RDBMS も利用可能

2014年2月12日に、RDBMS である Google Cloud SQL が正式リリースを迎えました。従来の使い慣れた RDBMS がよいという方はぜひ検討してみてください。

TechCrunch:「Googleの大規模データベースCloud SQLサービス、ついに正式公開―SLA、暗号化、サポートを提供」

全て Web リクエスト

サービス開発する上では、これが最も独特な仕様かもしれません。

cron も含め、全ての処理が URL をキックすることから始まります。また、1つのリクエストは30秒しか実行できません。cron や TaskQueue であれば10分間処理を実行できるため、複雑な処理を行う場合はこちらを利用しましょう。

cron も URL をキックするだけなので、文法が独特です。cron.yaml という、cron を記述したファイルをプロジェクトのトップに用意し、これをアップロードすることで cron 登録を行います(管理画面上では設定できないため、都度アップロードが必要です)

cron:
- description: execute some job 
  url: /crons/job_runner
  schedule: 24 of feb 9:00
  timezone: Asia/Tokyo

重要な処理を cron 経由で行う場合、cron を介してのみ実行可能なようにしないと、URL を叩くだけで実行できてしまいますので、ヘッダを見て制御しておきましょう:

if self.request.headers.get('X-AppEngine-Cron') is None:
    logging.error('This job must be executed via cron.')
    self.error(403)
    return

(上記ヘッダを偽装しても、管理者のログインでなければ GAE によって取り除かれると公式ドキュメントには解説されています。)

GoogleAppEngine を社内施策に利用した理由

サーバ不要

施策がどんな内容かはここではお伝えできないのですが、あまり社員数も多くない会社なので、気軽に始めて軌道修正を行う…いわゆるアジャイル的な開発には PaaS はうってつけです。

Gmail アカウントが楽に管理できる

中小企業やベンチャー企業だと、自前でメールサーバを持たず、全て Gmail(つまり GoogleApps)で済ませている会社も多いのではないでしょうか。そんな場合、GAE を使うメリットがいくつかあります:

GoogleApps の ID が使える

ユーザーの ID としてメールアドレスを利用することを考えると、そのメールアドレスが変わった場合は別ユーザーとして認識されてしまいます。GoogleApps はメールアドレスが ID ではなく、後から変更可能なため、メールアドレスを ID とすると扱いづらい側面があります。

GAE では GoogleApps のアカウント ID が参照できるため、メールアドレス周りの面倒な処理が必要ありません。

アカウントが存在するかを、メアドから参照可能

GAE ではメールアドレスから GoogleApps のアカウント ID を参照することができるため、その参照に失敗するかどうかで、そのメールアドレスが存在するかを判断することができます。

アカウントにログインしているかどうかの判定

GAE を利用する上で、GoogleApps にログインしているかどうかを判定できます。

if users.get_current_user():    # ログインしていれば User オブジェクトが返り、ログインしていなければ None が返る
    url = users.create_logout_url(self.request.uri)
    url_linktext = 'Logout'
else:
    url = users.create_login_url(self.request.uri)
    url_linktext = 'Login'

企業ドメインGoogleApps を利用している場合、その企業ドメインでのみ GAE を利用できるように利用制限することができるため、セキュリティも向上します。この設定は管理画面から設定可能です。(企業ドメインでの利用制限 = GoogleApps へのログインが必須なので、副次的にプログラム側でのバリデーション処理が少なくなります)

使い方によっては無料

PaaS ということで、オンプレ環境と違って、使った分だけ支払う形になります。逆に言えば、無料枠に収まれば無料で利用できます。

今回の社内施策は、特定のタイミングでメール配信、およびメール内のリンクを押下してもらう程度の簡単な仕組みだったため、今のところ無料で利用できていますが、無料枠はかなり少ない上、課金体系がかなり複雑なので、本格的なアプリケーションを組まれる方は料金に付いて一度精査した方がよいです。

参考にした情報

仕様変更や改訂が多いため、GoogleAppEngine の公式ドキュメントを頼るのが一番なのですが、BigTable 周りの解説が初心者にはかなりつらいので、「プログラミング GoogleAppEngine」という書籍を一読してから公式ドキュメントに当たるのがオススメです:

ちょっと古い部分もありますが、JavaPython どちらにも対応していますし、何より BigQuery について非常に丁寧に解説してあるため、これから開発される方はぜひ一度目を通していただきたいです。(でないと、トランザクション周りで苦しむことになります。。)

GAE は Python の書籍が少ないのが残念です。Google 的には、Android 開発を盛り上げたいという意図もあり、Java 推しなのでしょうが…。PaaS でサクっと開発したいのに主要言語が Java なのがミスマッチだなと感じます。上記は数少ない、Python の GAE 利用について書かれた日本語書籍です。

Python を書いたことないけど、Java で書くほどの処理は書かないし…」と思われる方でも、Python をお勧めします。Google の公式ドキュメントには Python のサンプルが豊富ですし、元々読みやすい言語なので、開発が楽しいです。GAE をきっかけに Python を使ってみてはいかがでしょうか。

何か不明点があればお気軽に!