Google App EngineのDBサービスはジョインができないなどの制約があるので,パフォーマンスを高めるには工夫が必要だ。キーワードは「キャッシュ」「非正規化」「分散」「事前計算」など。そのほか,処理性能の予測やフレームワークの利用などに注意したい。

 米Googleの「Google App Engine」(以下,GAE)は,Webアプリケーションの開発・実行環境を提供するサービスです。前回はGAEの概要編として,サービスの全体像や開発の流れ,データベース・サービスの概要などを説明しました。Java言語とPython言語で開発でき,各種ライブラリやアプリケーション・フレームワークがそろっている一方で,「データベースのジョインができない」といった制約があることを解説しました。

 今回はGAEの設計編として,GAE上で動作するアプリケーションを設計する際のコツを,主にデータベース設計を中心に解説します。

データベース設計のテクニック

 最初に,データベース・サービス(Datastore APIとして提供される)を簡単に復習しておきましょう。Datastore APIで利用できるデータベースは,Googleの検索サービスで使われているデータベース「BigTable」上に構築された,GAE専用のデータベースです。スケーラビリティに優れ,データは自動的に200Mバイトごとに分散して保存されますので,読み込み時のパフォーマンスは高いです。その半面,集約関数が使えない,ジョインができない,などの制約があります。図1には,Datastore APIを用いたコードの例と,データの格納形式を示しました。GAEのデータベースは「エンティティ」の集合で,エンティティは一つ以上の「プロパティ」からなります。プロパティは,識別子(図1のnameやtitle)と値(図1のJohnやpresident)からなります。

図1●Datastore APIの使用例とデータ格納形式
図1●Datastore APIの使用例とデータ格納形式
[画像のクリックで拡大表示]

 復習はこれくらいにして,ここから,主に制約を回避するために効果的な,データベース設計上のテクニックを六つ紹介します。

[テクニック1]Memcacheを使用する
 Datastoreからの読み出しは速いとはいえ,Datastoreに対して繰り返し同じクエリーを発行するのは避けるべきです。同じクエリーを繰り返し発行するような場合には,メモリーをキャッシュとして使うライブラリ「Memcache」を活用するとよいでしょう。

 その際の基本パターンは図2のようになります。4行目でDatastoreからデータを取得し,その結果を5行目でメモリー(Memcache)に格納しています。同じクエリーを発行する場合,2回目以降はMemcacheに対してアクセスするようにすれば,Datastoreより高速なアクセスが可能になります。

図2●Memcacheの使用例
図2●Memcacheの使用例
[画像のクリックで拡大表示]

[テクニック2]非正規化を積極的に行う
 RDBMSを使ったシステムのデータ・モデルを設計する際,正規化を行うのが普通で,ほとんどの場合,非正規化は悪いこととされています。この考え方は,GAEのDatastoreでは捨て去るつもりで設計する必要があります。なぜなら,テーブル間のジョインが気軽にできるRDBMSと違って,Datastoreでは基本的にジョインができないからです。

 例を使って説明しましょう。「東京都に住む30歳以下の人物」を検索するアプリケーションを考えます。図3上はRDBMSを用いたケースで,正規化の考えに基づいて,「Person」(人物)テーブルと「Prefecture」(都道府県)テーブルに分かれています。Prefectureテーブルを都道府県マスターとするわけです。これらのテーブルを使ったクエリー(東京都に住む30歳以下の人物を検索)は図3下のようになります。二つのテーブルをジョインすることで,1回のクエリーで済んでいます。

図3●RDBMSを用いた例
図3●RDBMSを用いた例
[画像のクリックで拡大表示]

 RDBMSと同じ発想で,Datastoreを使ってデータ・モデルを作ると,図4上のようになるでしょう。Personクラスのprefectureメンバーは,Prefectureエンティティの参照を保持することを意味しています。このデータ・モデルの場合,ジョインができないので,図4下のようにクエリーを2回発行する必要があり,効果的とはいえません。

図4●RDBMSと同じ発想でDatastoreを用いた例
図4●RDBMSと同じ発想でDatastoreを用いた例
[画像のクリックで拡大表示]

 クエリーを1回で済ませるには,RDBMSの常識を捨ててクラスを一つに(非正規化)します。具体的には図5上のようなデータ・モデルで,同下のようなクエリーを1回発行するだけで,「東京都に住む30歳以下の人物」を検索することができます。都道府県データを見直すような変更が必要になると大幅にデータを修正しなければなりませんが,高いパフォーマンスが求められる場合,Datastoreではこのような非正規化を積極的に行うべきでしょう。

図5●クエリーが1回で済むDatastoreを用いた例
図5●クエリーが1回で済むDatastoreを用いた例
[画像のクリックで拡大表示]