マルチテナンシーアーキテクチャ(Multi-tenancy Architecture)
1. 概要
マルチテナンシー(Multi-tenancy)とは、単一のアプリケーションインスタンスと共有インフラの上で多数の顧客(テナント、Tenant)を同時に収容しつつ、各テナントが論理的に隔離された専用環境を使っているかのように感じるよう設計するソフトウェアアーキテクチャ方式である。
SaaS(Software as a Service)の登場はソフトウェア供給モデルを「製品販売」から「サービス購読」へと変え、この転換の経済性を支える中核技術がまさにマルチテナンシーである。従来のオンプレミス・ホスティングモデルでは顧客ごとに別個のサーバ・DB・アプリケーションインスタンスを構築したため、顧客が1,000社に増えれば運用対象も1,000組に増え、保守・パッチ・監視コストが線形に増加した。これに対しマルチテナンシーは資源を共有プール(pool)にまとめ、一度の配備・パッチで全顧客を同時に更新するため、顧客増加に伴う限界費用を劇的に下げる。Salesforceが2000年代初めに単一コードベースで数十万組織を収容しSaaS市場を開いたのが代表的な事例である。
マルチテナンシーが単なる「サーバ共有」と異なる点は、テナント隔離(Isolation)と資源効率(Efficiency)という相反する二つの目標を同時に達成しなければならないところにある。隔離を極端に追求すればテナントごとに専用資源を与えることになり効率が落ち(事実上シングルテナンシー)、効率を極端に追求すれば一つのテナントの障害・過負荷・データが他のテナントへ伝播する危険が高まる。したがってマルチテナンシー設計の本質は「隔離と効率の間のどの地点で均衡をとるか」をデータ・計算・運用・課金の各層別に決めることである。本稿は隔離モデル、中核的設計課題(テナント識別・Noisy Neighbor・セキュリティ)、データ隔離モデルの比較、実務適用事例、そして技術士の観点からの考慮事項を深化レベルで扱う。
マルチテナンシーは次のような特徴をもつ。第一に、単一の論理インスタンスで全テナントを収容し運用の単純性を確保する。第二に、すべての要求にテナントコンテキスト(Tenant Context)が伴い、データ・設定・権限がテナント単位で分岐する。第三に、構成(Configuration)ベースのカスタマイズによりコード分岐なしにテナント別の画面・ワークフロー・フィールドを提供する。第四に、資源を共有するため弾力的な拡張とコスト配分(Chargeback/Showback)が設計の一部となる。
2. マルチテナンシーの全体構造
マルチテナンシーシステムは、要求が入ってくる瞬間からテナントを識別し、そのコンテキストを全層に伝播させ、最終的にテナント別に分離されたデータへアクセスする垂直的隔離パイプラインで構成される。下の構造図はその全体の流れを示す。
graph TD
U1["テナントAユーザ"] --> GW["API Gateway / ルータ"]
U2["テナントBユーザ"] --> GW
GW --> RES["テナント識別(Tenant Resolver)<br/>サブドメイン・トークン・ヘッダ"]
RES --> CTX["テナントコンテキスト注入<br/>(Tenant Context)"]
CTX --> APP["共有アプリケーションインスタンス"]
APP --> POL["隔離・権限ポリシエンジン<br/>(RLS・フィルタ・クォータ)"]
POL --> DL["データアクセス層"]
DL --> DBA[("テナントAデータ")]
DL --> DBB[("テナントBデータ")]
APP --> CFG["テナント別構成ストア<br/>(設定・メタデータ)"]
POL --> QOS["資源クォータ・Rate Limit"]
上の構造で最初に働く要素がテナント識別(Tenant Resolver)である。要求がどのテナントに属するかを信頼できる形で判別できなければ、その後のすべての隔離は無意味である。識別方式にはサブドメイン(tenant-a.service.com)、URLパス(/t/tenant-a/...)、認証トークン(JWTのtenant_idクレーム)、HTTPヘッダなどがあり、実務ではJWTクレームを第一の信頼根拠とし、サブドメインはルーティングの便宜としてのみ用いるのが安全である。URLやヘッダのようにクライアントが任意に変えられる値を唯一の根拠とすれば、テナント偽装(Tenant Impersonation)攻撃にさらされるためである。
識別されたテナントIDはテナントコンテキストへ昇格され、要求処理の全区間に伝播される。JavaのThreadLocal、Springの要求スコープBean、Node.jsのAsyncLocalStorageなどが使われ、非同期・スレッドプール環境でコンテキストが失われたり、他の要求のコンテキストと交差汚染(cross-contamination)されたりしないよう伝播メカニズムを厳格に管理せねばならない。実際にマルチテナンシーの最も致命的な事故の多くが「A要求がBのコンテキストで処理されデータが漏洩する」類型であり、これはコネクションプール再利用・キャッシュキー欠落・グローバル変数の誤用から生じる。
A. 隔離水準(Isolation Level)のスペクトラム
マルチテナンシーは「隔離するか/しないか」の二分法ではなく、資源層ごとに共有(Pool) ↔ 専用(Silo)の間のスペクトラム上で組み合わされる設計である。下の図は三つの代表モデルが隔離と効率の軸でどこに位置するかを示す。
graph LR
subgraph POOL["Poolモデル: 完全共有"]
P1["共有DB<br/>共有スキーマ<br/>tenant_idカラム"]
end
subgraph BRIDGE["Bridgeモデル: 部分隔離"]
B1["共有DB<br/>テナント別スキーマ"]
end
subgraph SILO["Siloモデル: 完全隔離"]
S1["テナント別<br/>専用DB・インスタンス"]
end
POOL -->|"隔離強化 →"| BRIDGE
BRIDGE -->|"隔離強化 →"| SILO
SILO -->|"← 効率強化"| BRIDGE
BRIDGE -->|"← 効率強化"| POOL
Poolモデルは全テナントが同一のDB・スキーマ・テーブルを使い、各行(row)にtenant_idカラムで所属を表示する。資源効率と運用単純性が最も高いが、すべてのクエリにテナントフィルタが漏れなく適用されねばならず、一つのテナントの大容量データが共用インデックスを膨張させるなど干渉の危険が大きい。Siloモデルはテナントごとに専用DB(または専用インスタンス・専用アカウント)を置き隔離が最も強く、規制対応・性能保証・テナント別バックアップ・復元が容易であるが、テナント数だけ運用対象が増え、パッチ・監視・スキーマ移行コストが急増する。Bridge(Hybrid)モデルは一つのDBの中でテナント別スキーマ(またはテーブル接頭辞)で区分し両極端の折衷をとる。実務では「大多数の小規模テナントはPoolで、大型・規制顧客はSiloで」収容するティアド(tiered)・混合戦略が最も一般的である。
B. データ隔離モデルの比較
データ層の隔離モデル選択はマルチテナンシー設計で最も波及力が大きい決定である。下の表は三モデルのトレードオフを整理するが、選択の「理由」は表の後の散文で説明する。
| 区分 | Pool(共有スキーマ) | Bridge(テナント別スキーマ) | Silo(専用DB) |
|---|---|---|---|
| 隔離水準 | 低(論理的) | 中 | 高(物理的) |
| 資源効率 | 非常に高い | 高い | 低い |
| テナント当たりコスト | 非常に低い | 低い | 高い |
| カスタマイズ | 限定的 | スキーマ単位で可能 | 完全に自由 |
| バックアップ・復元(テナント単位) | 困難 | 中 | 容易 |
| スキーマ移行 | 1回で全体 | テナント数だけ反復 | テナント数だけ反復 |
| 規制・データ主権対応 | 困難 | 普通 | 容易 |
| 適合規模 | 数千~数百万の小型テナント | 中規模 | 少数の大型・規制顧客 |
Poolモデルがコスト・拡張性で圧倒的に有利な理由は、運用単位がテナント数と無関係に「1」で固定されるためである。10万テナントのスキーマを変えねばならないとき、Poolは単一のALTER TABLEで終わるが、Siloは10万回の移行をオーケストレーションせねばならず、その一部が失敗すればテナント間でスキーマバージョンが食い違うドリフト(drift)問題が発生する。逆にSiloが規制産業(金融・医療・公共)で好まれる理由は、テナントデータが物理的に分離され「他の顧客データと混ざらない」ことを監査(audit)で立証しやすく、特定の国にデータを置かねばならないデータ主権(Data Sovereignty)要件やテナント単位の選択的削除(GDPRの削除権)要求を自然に充足するためである。例えばEU顧客データをフランクフルトリージョン専用DBに置き、米国顧客はバージニアリージョンに置くといった分離は、Siloで簡明に実装される。
Poolモデルを安全に運用する中核装置が行レベルセキュリティ(Row-Level Security, RLS)である。アプリケーションコードのWHERE tenant_id = ?フィルタは、開発者が一箇所でも漏らせば全テナントデータが露出する単一障害点となる。PostgreSQLのRLSポリシのようにDBエンジン水準でセッション変数(SET app.tenant_id)に基づき自動でテナントフィルタを強制すれば、アプリケーションにバグがあってもDBが最後の防御線の役割を果たす。これは「アプリケーションを信じるな、データ層で隔離を強制せよ」という深層防御(Defense in Depth)原則の適用である。
C. テナントのオンボーディングとライフサイクル管理
マルチテナンシーはランタイム隔離だけでなく、テナントの生成→運用→解約に至るライフサイクル自動化が裏付けられてはじめて運用が成立する。新規テナントのオンボーディング時にはテナントレコード生成、専用資源(SiloならDB・スキーマ)のプロビジョニング、初期管理者アカウント・既定構成の注入、隔離ポリシの適用が、冪等的(idempotent)かつ自動化されたパイプラインで実行されねばならない。手作業のオンボーディングはテナントが数百を超えた瞬間にボトルネックとなる。
テナント解約(off-boarding)はしばしば見落とされるが法的に重要である。GDPR・個人情報保護法はデータ削除・移転(portability)要求を規定するため、解約時に当該テナントデータを完全かつ検証可能に削除し(または暗号化鍵の破棄でアクセス不能化し)、削除証跡を残す手順が設計に含まれねばならない。Poolモデルで特定のテナントだけを削除するには大容量テーブルで大量DELETEが発生し性能に影響するため、暗号消去(Crypto-shredding)——テナント別暗号化鍵を破棄しデータを事実上復旧不能にする手法——が実務的な代替として用いられる。
3. 中核的設計課題
A. Noisy Neighbor(騒がしい隣人)問題
マルチテナンシーで資源を共有するとき最も頻繁な運用課題がNoisy Neighborである。一つのテナントが異常に多くのCPU・メモリ・I/O・コネクションを消費すると、同じプールを使う他のテナントたちの応答遅延とエラーが共に跳ね上がる。例えば一つのテナントが数百万行を照会する重いレポートクエリを繰り返し実行すると、DBコネクションプールが枯渇し全テナントの要求がキューに積み上がる。2010年代の複数のSaaS障害の事後分析で「特定の大型顧客のバッチ作業が全サービスを低下させた」事例が繰り返し報告された。
対応は多層的である。アプリケーション層ではテナント別のRate Limitingと同時実行クォータを置き、一つのテナントが消費できる要求率・コネクション数を上限する。資源層ではセル(Cell)ベースアーキテクチャ——テナントを複数の独立セル(完結した資源の束)に分散配置し一つのセルの障害が他のセルへ波及しないようにする方式——が有効である。またバルクヘッド(Bulkhead)パターンでテナント群ごとに別個のコネクションプール・スレッドプールを割り当てれば障害伝播を防げる。重要な点は、Noisy Neighborが「性能問題」に見えるが本質は公正性(Fairness)と隔離の問題であり、共有効率を放棄せずに公正性を保証することが設計の妙であるという点である。
B. テナント間データ漏洩(Cross-Tenant Data Leakage)の防止
マルチテナンシー最大のセキュリティ脅威は、一つのテナントが他のテナントのデータを見てしまう事故である。原因は主に、① クエリのテナントフィルタ欠落、② キャッシュキーにテナントID不含(テナントAが照会した結果がキャッシュに残りBへ返される)、③ コンテキスト汚染(非同期処理中のコンテキスト混線)、④ 識別子を推測可能なIDOR(Insecure Direct Object Reference)などである。OWASPはこうしたテナント隔離の欠陥を深刻なアクセス制御違反に分類する。
防御は「幾重もの網」で構成する。第一に、先に説明したDB RLSでデータ層でテナントフィルタを強制する。第二に、キャッシュ・検索エンジン・メッセージキューなどすべての補助ストアのキー・インデックスにテナントIDを必ず含める(例: Redisキーtenant:{id}:user:{uid})。第三に、オブジェクト識別子は推測不能なUUIDを使い、アクセス時に所有テナントを再検証する。第四に、自動化テストにクロステナントアクセス試行ケースを常時含め、「AトークンでBリソースを要求すれば403が出るか」を回帰検証する。マルチテナンシーではこの陰性ケース(negative test)が機能テストと同じくらい重要である。
C. テナント別構成とカスタマイズ
SaaS顧客はそれぞれ異なる画面・フィールド・ワークフロー・ブランディングを望むが、マルチテナンシーは単一コードベースを維持せねばならない。したがってカスタマイズはコード分岐(fork)ではなく、構成(Configuration)とメタデータ主導(metadata-driven)方式で吸収する。テナント別設定を外部ストアに置きランタイムに読み込んでUI・検証規則・機能フラグを分岐させ、拡張フィールド(custom field)はEAV(Entity-Attribute-Value)やJSONBカラムでスキーマ変更なしに収容する。Salesforceが数十万組織に互いに異なるオブジェクト・フィールド・画面を提供しながらも単一プラットフォームを維持する秘訣が、まさにこのメタデータ主導アーキテクチャである。
ここに機能フラグ(Feature Flag)と料金ティア(Tier)を結合すれば、同一コードでテナントごとに異なる機能集合を露出し上位料金制にのみ高度な機能を開放する資源・機能の差別化提供が可能になる。これはカスタマイズを超えてビジネスモデル(価格差別化)と直結するアーキテクチャ要素である。
D. テナント認識オブザーバビリティとSLA差別化
マルチテナンシーではすべてのログ・指標・トレースにテナントIDが次元(dimension)として付着されねばならない。共有インスタンスで発生したエラーがどのテナントの要求から生じたか、応答遅延が特定のテナントに集中するかを区別できなければ、障害対応と原因分析が不可能になる。したがって構造化ロギング(structured logging)にtenant_idを常時含め、メトリクスにテナントラベルを付け、分散トレーシング(distributed tracing)のスパンにテナント属性を伝播させるテナント認識オブザーバビリティ(Tenant-aware Observability)が運用の前提となる。ただしテナント数が数十万に達するとテナント別メトリクスのカーディナリティ(cardinality)爆発が監視コストを押し上げるため、上位ティア・大型テナントにのみ細分指標を収集し残りは集計指標で管理する選別戦略が必要である。
オブザーバビリティはSLA(サービス水準合意)差別化とも連結する。マルチテナンシーで全テナントに同一のSLAを約束すれば、共有資源の限界により上位顧客の期待を満たしにくい。したがってティア別に応答時間・可用性目標を違え、これを裏付けるよう上位ティアのテナントを専用セル・専用コネクションプールに配置する形でアーキテクチャと契約を整合させる。例えば無料ティアは共用Poolでベストエフォートで、エンタープライズティアは専用シャードで99.95%の可用性を保証する構造が典型的である。
4. 適用事例と比較
マルチテナンシーの隔離戦略は産業の規制強度と顧客構成によって大きく分かれる。コラボレーションSaaS(Slack・Notion・Salesforceなど)は数十万~数百万の小規模テナントを低コストで収容せねばならないためPoolモデルを基本とするが、大型エンタープライズ顧客には専用シャード・専用リージョンを提供する混合戦略を使う。これに対し金融・ヘルスケアSaaSは規制・監査要件上、Siloに近い隔離を選ぶ場合が多く、テナントデータの物理的分離と専用暗号化鍵を強調する。
クラウド事業者もマルチテナンシーの巨大な実際の事例である。AWS・Azure・GCP自体が数百万顧客を共有ハードウェアの上で仮想化・ハイパーバイザで隔離するマルチテナントプラットフォームであり、ここに顧客が「専用ハードウェア(Dedicated Host)」を選べば、一段階強い隔離をコストと引き換える構造である。Kubernetes環境ではネームスペースベースのソフトマルチテナンシー(ネームスペース・RBAC・ResourceQuota・NetworkPolicyで区分)と、クラスタ分離ベースのハードマルチテナンシー(テナント別専用クラスタ)、そして仮想クラスタ(vCluster)のような中間方式がスペクトラムをなす。コンテナはカーネルを共有するためソフトマルチテナンシーの隔離は仮想マシンより弱く、強い隔離が必要ならKata Containers・gVisorのようなサンドボックスランタイムで補強する。
規模の経済を数字で見るとマルチテナンシーの動機が明確になる。テナント当たり専用スタック(Silo)を運用する組織が顧客1,000社を収容するには1,000組のアプリケーション・DBをパッチ・監視せねばならず、平均稼働率の低い小型顧客の資源が大部分遊休で残るため、単位顧客当たりインフラ原価が高く固定される。これに対しPoolマルチテナンシーは同一資源プールを全顧客が時分割するため平均稼働率を引き上げ、同じハードウェアで数十倍の顧客を収容できる。実際に大型コラボレーションSaaSは数百万テナントを少数の共有セル集合で収容し、この密度(density)が購読型価格をオンプレミス比で劇的に下げる源泉となる。ただしこの効率は「一つのテナントのピークが他のテナントの余裕と相殺される」という統計的多重化(statistical multiplexing)の仮定に依存するため、すべてのテナントのピークが重なる時間帯(例: 月末精算)には全資源が同時に圧迫される相関負荷(correlated load)の危険を併せて設計せねばならない。
シングルテナンシー(テナント当たり専用スタック)との比較で差が生じる根本理由は、「誰が運用複雑度を引き受けるか」にある。シングルテナンシーは隔離・カスタマイズ・バージョン独立性で有利だが、その代価としてテナント数に比例する運用負担を事業者が負う。マルチテナンシーは運用を単一化し規模の経済を得る代わりに、隔離と公正性をソフトウェアで保証せねばならない設計難度を引き受ける。したがって「少数の大型・高規制顧客」ならシングル/Siloが、「多数の小型顧客を低価で」ならPoolマルチテナンシーが合理的であり、大部分の成熟したSaaSは両者をティアで結合する。
5. 深化: SaaS成熟度モデルとサーバレスマルチテナンシー
マイクロソフトが提示したSaaS成熟度モデル(Maturity Model)はマルチテナンシーの進化段階を4レベルで説明する。レベル1(Ad-hoc/Custom)は顧客ごとにコード・インスタンスを分離した事実上のホスティングモデルであり、レベル2(Configurable)は単一コードベースを構成でカスタマイズするがインスタンスは分離し、レベル3(Configurable + Multi-tenant)は一つのインスタンスで複数テナントを収容し、レベル4(Scalable Multi-tenant)はロードバランスされた多数のインスタンスでテナントを動的に分散し事実上無限の拡張を志向する。このモデルは「マルチテナンシーが完成形ではなく組織の成熟に応じて段階的に到達する目標である」ことを示唆し、技術士の答案で現行水準の診断と目標アーキテクチャの提示の枠として有用である。
最近の流れはサーバレス・セルベースのマルチテナンシーへ移動している。AWSはSaaS設計指針であるSaaS Lensと参照アーキテクチャで「プール・サイロ・ブリッジの混合をテナントティア別に適用せよ」と勧告し、Lambda・DynamoDBのようなサーバレス資源では資源自体が自動拡張されるためNoisy Neighborをインフラ水準で相当部分吸収する。ただしサーバレスでもテナントコンテキスト伝播とデータ隔離(DynamoDBのパーティションキーにtenant_idを含める、IAMポリシの条件付きアクセスなど)は依然として設計者の役目である。さらにセルベースアーキテクチャ(Cell-based Architecture)はテナントを完結的なセル単位に分散し障害半径(blast radius)をセルに限定する方式で、大規模マルチテナントサービスの可用性・隔離を同時に引き上げるパターンとして注目される。生成AI SaaSではテナント別の埋め込み・ベクトルインデックスの隔離、テナントデータが共用モデル学習に混ざらないようにするデータ境界の保証が新たなマルチテナンシー課題として浮上している。
6. 考慮事項および示唆点
マルチテナンシーはSaaSの経済性を決定する戦略的選択であるため、技術士の観点では単一技術ではなくデータ・セキュリティ・運用・ビジネスを貫く設計意思決定フレームとして接近せねばならない。
隔離-効率トレードオフの層別分離設計: 「すべてPool」または「すべてSilo」の画一的選択を避け、データ・計算・ネットワーク・課金の層ごとに隔離水準を違えるティアド戦略を採択する。小型顧客はPoolでコストを下げ、大型・規制顧客はSiloで隔離を保証しつつ、両モデル間のテナント昇格(Pool→Silo移行)経路をあらかじめ設計し成長に対応する。
セキュリティ: 深層防御と陰性テストの義務化: アプリケーションフィルタ一つに隔離を依存せず、DB RLS・キャッシュキー分離・識別子の非推測性を重ねる。特に「クロステナントアクセス遮断」をCIパイプラインの常時回帰テストとして置き、コード変更が隔離を壊す瞬間にビルドが失敗するようにする。テナント隔離の欠陥は一度発生すれば全顧客の信頼を失う致命的事故であることを前提に設計する。
運用: スキーマ進化とブルーグリーン・漸進配備: 単一コードベースの長所は「一度直せば全員適用」だが、裏返せば「一度誤れば全員障害」である。したがってスキーマ移行は後方互換(backward-compatible)段階(拡張→二重書き込み→切替→整理)に分解し、新規バージョンを少数のテナントに先に配備するカナリア・リング配備で危険を制御する。テナント別バックアップ・復元(Point-in-time)とテナント単位のロールバック可能性も運用設計に含める。
コスト可視性と課金連携(FinOps): 資源を共有するため「どのテナントがいくらのコストを引き起こしたか」を測定しにくい。テナント別資源使用量を計測(metering)しShowback/Chargebackと料金ティアに連結すれば、コスト異常テナントを早期に識別し価格政策をデータに基づき設計できる。マルチテナンシーのコスト効率は測定・配分体系が裏付けられてはじめてビジネス価値に転換される。
規制・データ主権対応: GDPR・個人情報保護法・網分離・CSAPなどの規制はデータ位置・削除・分離を要求する。リージョン別テナント配置、テナント別暗号化鍵と暗号消去、削除証跡の保管を設計初期に反映せねばならず、事後改造はPoolモデルであるほどコストが大きい。展望としてはAI SaaSのデータ境界保証とセルベース・サーバレスマルチテナンシーが隔離と拡張を同時に要求する次世代課題として浮上するであろう。
参考資料
- AWS, "SaaS Architecture Fundamentals" / SaaS Lens, AWS Well-Architected: https://docs.aws.amazon.com/wellarchitected/latest/saas-lens/saas-lens.html
- Microsoft, "Multitenant SaaS architecture patterns" (Azure Architecture Center): https://learn.microsoft.com/en-us/azure/architecture/guide/multitenant/overview
- Google Cloud, "Multi-tenancy best practices (GKE)": https://cloud.google.com/kubernetes-engine/docs/concepts/multitenancy-overview
- PostgreSQL Documentation, "Row Security Policies": https://www.postgresql.org/docs/current/ddl-rowsecurity.html
- Salesforce, "The Multitenant Architecture of the Salesforce Platform": https://developer.salesforce.com/wiki/multi_tenant_architecture
一言まとめ: マルチテナンシーは共有インフラで多数のテナントを収容しつつ隔離と効率を同時に追求するSaaSの中核アーキテクチャであり、データ・セキュリティ・運用・課金の各層でPool・Bridge・Siloの隔離水準をティア別に組み合わせ、RLS・Rate Limit・セルベース設計でデータ漏洩とNoisy Neighborを制御することが成否を分ける。