web-dev-qa-db-ja.com

django)のマルチテナントアプリケーションに最適なアーキテクチャ

私は、Djangoに基づいてマルチテナンシーアプリケーションを作成するための正しい/最適な方法を模索してきました。

いくつかの説明:

  • アプリケーションは、複数のテナント(tenant1、tenant2、...、)で使用できます。

  • すべてのテナント個人データは、他のテナント(およびそのユーザー)のアクセスから保護する必要があります。

  • オプションで、テナントはアプリケーションオブジェクト用に追加のカスタムフィールドを作成できます。

  • もちろん、基盤となるハードウェアは、1つの「システム」上のテナントの数を制限します。

1)各テナントを例:サブドメインおよび基盤となるレイヤーでのテナント固有のデータベースの使用

2)モデル内のテナントIDを使用して、データベース内のテナントデータを分離します

展開プロセス、システムパーツ(Webサーバー、データベースサーバー、作業ノードなど)のパフォーマンスについて考えています。

最適な設定は何ですか?長所と短所はどこにありますか?

どう思いますか?

61
Oliver Rehburg

次のアーキテクチャを使用して、マルチテナンシーを構築しました platform 。役立つヒントが見つかるといいのですが。

  • 各テナントはサブドメイン(t1.example.com)を取得します
  • URL書き換えを使用すると、Djangoアプリケーションのリクエストは、example.com/t1のようなものに書き換えられます。
  • すべてのURL定義には、_(r'^(?P<tenant_id>[\w\-]+)_のようなプレフィックスが付いています。
  • ミドルウェア はtenant_idを処理して消費し、それをリクエストに追加します(例:request.tenant = 't1')
  • これで、すべてのビューでtenant_id引数を指定しなくても、各ビューで現在のテナントを使用できるようになりました。
  • 場合によっては、リクエストを利用できないことがあります。私はtenant_idを現在のスレッドにバインドすることでこの問題を解決しました( 現在の言語 _threading.local_を使用するのと同様)
  • デコレータ(テナント対応の_login_required_など)、ミドルウェア、またはファクトリを作成して、ビューを保護し、適切なモデルを選択します
  • データベースに関しては、2つの異なるシナリオを使用しました:
    • 複数のデータベースをセットアップし、現在のテナントに従って ルーティング を構成します。私はこれを最初に使用しましたが、約1年後に1つのデータベースに切り替えました。その理由は次のとおりです。
      • データを分離するための安全性の高いソリューションは必要ありませんでした
      • 異なるテナントはほぼすべて同じモデルを使用しました
      • 多くのデータベースを管理する必要がありました(そして、簡単な更新/移行プロセスを構築しませんでした)
    • ユーザーやさまざまなモデル用のいくつかの単純なマッピングテーブルを備えた1つのデータベースを使用します。追加のテナント固有のモデルフィールドを追加するには、 モデル継承 を使用します。

環境に関しては、次の設定を使用します。

私の観点からすると、このセットアップには次の長所と短所があります。

プロ:

  • 現在のテナントを知っている1つのアプリケーションインスタンス
  • プロジェクトのほとんどの部分は、テナント固有の問題を気にする必要はありません
  • すべてのテナント間でエンティティを共有するための簡単なソリューション(メッセージなど)

対照:

  • 1つの非常に大きなデータベース
  • モデルの継承によるいくつかの非常に類似したテーブル
  • データベース層で保護されていません

もちろん、最適なアーキテクチャは、テナントの数、モデルのデルタ、セキュリティ要件などの要件に大きく依存します。

更新:アーキテクチャを確認したので、ポイント2に示すようにURLを書き換えないことをお勧めします-3。より良い解決策は、_tenant_id_をリクエストヘッダーとして配置し、request.META.get('TENANT_ID', None)のようなものでリクエストから_tenant_id_を抽出(ポイント4)することだと思います。このようにしてニュートラルなURLを取得し、Django組み込み関数(例:_{% url ...%}_またはreverse())または外部アプリを使用する方がはるかに簡単です。

55
Reto Aebersold

関連する議論へのいくつかのポインタは次のとおりです。

4
akaihola

https://github.com/bcarneiro/Django-tenant-schemas をご覧になることをお勧めします。 postgresqlスキーマを使用することを除いて、Retoが述べたように問題を少し解決します。

1
Clash