マルチテナントアーキテクチャ
アーキテクチャの検討事項
アプリケーションの分割
ドメインとログイン画面の分割
複数のテナントに同時にログインできる(Cookieをサブドメインで分ける)
過負荷時に、特定ドメインを別リソースに振り分けられる
分割アプローチ
1. 分離(isolated): DBを分ける(≒ シングルテナントDB)
2. 準分離(semi-isolated): DBは1つ、スキーマ/名前空間を分ける
3. 共有(shared): DB/スキーマを分けない
コネクション共有/分離、プール
ストレージの分割
Blogストア/S3等の空間を分ける
DISKのパスを分ける
キャッシュを分ける
KVSを分ける
一部のテナントがCPU/DISKを占拠した場合の制御
運用監視
ログ出力を分ける、テナント識別子を付ける
「最も効率的な真のマルチテナンシー」は、全てのリソースをシェアする方式(以下のIBM developerworksの記事より)。
記事が消えているので、WebArchiveで参照
マルチテナンシーには、いくつかのレベルがあります (下記の図を参照)。
1. クラウド内での単純な仮想化により、ハードウェアのみを共有
2. 1 つのアプリケーションで、テナントごとに異なるデータベースを使用
3. 1 つのアプリケーションでデータベースを共有 (最も効率的な真のマルチテナンシー)
マルチテナンシーのモデル
https://scrapbox.io/files/6083553ba56439001c59e950.png
参考情報
DB分割アプローチとして「分離/準分離」を選択している記事
マルチテナントについての様々な情報へのリンクを提供してくれている
私が経験したマルチテナントアーキテクチャはオーソドックスな2です。
顧客データを全て一つのDBに混ぜてしまうのはデータ混濁のリスクが怖いのでDBの機能・ユーザーでデータを分離してしまうパターンです。 また、世のOSSのWebフレームワーク、DBフレームワーク(含むORマッパ)はたいていシングルテナント前提に作られていますから、OSSの恩恵を受けつつマルチテナントを実現しようとするとだいたいこの選択になるかと思います。
shimizukawa.icon RLSによって解決できそう 開発時の考慮すべき点
テナント毎にドメインを分け、ログイン画面も分けよう
DBの接続先の切り替えはユーザーのリクエストを処理する最初の段階でフレームワークレベルで行う
コネクション確立コストの高いRDBMSではコネクションプールを用意しよう
テナントのデータを処理しているログにはテナントを特定できるキーが出るようにしよう
ログインについてはSSOの仕組みをなるべく備えておこう
クォータ・スロットリング
(レベル1)全利用者が同一データベース、同一スキーマを共有
全利用者が1つのインフラを共有し、運用も共通化できるため、もっとも効率の良いマルチテナントアーキテクチャ。セールスフォースはこの方式を採用。
(レベル2)全利用者が同一データベースを共有。スキーマは個別。あるいはスキーマは同一で、データベースは個別
工夫次第でインフラの共有は可能だが、スキーマ管理や運用管理は個別に行うことになり、運用に手間がかかる。
(レベル3)利用者ごとに個別のデータベース、個別のスキーマ
利用者からの個別のリクエストに柔軟に対応しやすくなるが、しかしデータベースの種類が増えて管理が面倒になり、運用の手間がかかる。共有部分も減り、インフラの利用効率も悪い。