emahiro/b.log

Drastically Repeat Yourself !!!!

App Engineでマルチテナントなアプリを作る

Google App Engine上でマルチテナントなアプリを作る方法について調査したのでブログにまとめてみます。

マルチテナントとは?

IT用語辞典には以下のように記載されています。

マルチテナントとは、SaaSクラウドコンピューティングなどで、機材やソフトウェア、データベースなどを複数の顧客企業で共有する事業モデル。

マルチテナントとは1つのアプリケーションを複数のクライアントで共有することを意味します。

App Engineにおけるマルチテナント

App Engineは Namespace API を使ったマルチテナントの実装がサポートされています。 具体的には 公式ドキュメント に以下のように記載されています。

複数のクライアント組織に対応する個別のデータ パーティション(テナント)を提供することで、「マルチテナンシー」をサポートできます。これにより、すべてのテナントで同じデータスキーマを保持しながら、各テナントのデータ値をカスタマイズできます。マルチテナンシーではテナントを追加するときにデータ構造を変更する必要がないため、新しいテナントのプロビジョニングが効率的になります。

これにより、1つのアプリケーションをNamespaceで区切られた複数の環境で同じように動作させることが可能で、さらにこのNamespaceで区切られた環境は互いに干渉することはありません。

Namespace API

マルチテナントアプリケーションを実現するために App Engineでは Namespace API が用意されています。

cloud.google.com

ドキュメントに記載されていますが、現在サポートされてる言語は javapython、goに3言語で、Namespace API名前空間を使用するApp Engine(※1)のサービスは以下です。

  • Datastore
  • MemCache
  • Task Queue
  • Search

※1. google.golang.org/appengine のappengine package。cloud.google.comの方ではない。

このAPIを使ってマルチテナントアプリケーションを構築することで、例えば以下のようなことが可能になります。

  • Namspaceで区切られた環境は互いに干渉することがないのでそれぞれ独立したアプリケーションとして動かすこと。
  • ある名前空間を持つ環境で操作したデータが別の名前空間に影響するようなことがない状態を作ること。
  • これにより 1つのコードベースで様々な用途の環境を同時に複数用意する こと。(ex. 検証環境 etc...)

実装方法

具体的な実装方法については 公式のドキュメントを参照してください。ここでは名前空間を指定してDatastoreの新しいデータを追加する方法について記載します。

// 登録する名前空間をcontextに入れる
ctx, err := appengine.Namespace(appengine.NewContext(req), "emahiro")
if err != nil {
   panic(err)
}

key := datastore.NewKey(ctx, "SampleKind", "prop", 0, nil)
// datastoreのput処理

これだけで名前空間で区切られた環境にデータが登録されます。consoleでは以下のようにKindを選ぶ前に名前空間を選ぶUIが表示されるようになります。
ここではAppEngineのデフォルトの名前空間の他に新しく登録した emahiro という名前空間が作られていることがわかります。

※ 繰り返しになりますが、詳細な実装方法、およびDatastore以外の実装については公式ドキュメントを参考にしてください。

contextのなかに Namespaceの文字列を入れるだけという非常にシンプルな方法で名前空間を分けてデータを入れることができました。
ここでは Datastoreでの実装方法を記載しましたが、Namespace APIは DatastoreとMemCacheの両方で使われるので https://github.com/mjibson/goon を使っていてもマルチテナントアプリケーションに対応できます。(Goonも中ではdatastoreのAPIを使っているで。)

まとめ

  • App Engineにはマルチテナントアプリケーションを構築できる機能が備わっている。
  • Namespace APIを使うと簡単に名前空間を設定可能。
  • 分けられた名前空間は互いに干渉しないので、検証や配布など様々な用途で使うことができる。

参考資料