web-dev-qa-db-ja.com

サーバークラスタリング(Django、Apache、Nginx、Postgres)

Django、Apache、Nginx、Postgresでプロジェクトをデプロイしています。このプロジェクトには、顧客が閲覧できるライブデータが必要です。プロジェクトの主なポイントは次のとおりです。1。フィールド内のデバイスは、ログイン後にサーバーにデータを送信します(デバイスはWebサイトユーザーのようなものです)。 2.postgresでアップロードされたデータをインポートするバックグラウンドインポートプロセスがあります。 3.システムのWebユーザーはこのデータを使用して、デバイスにコマンドを送信できます。デバイスは、ログイン時に読み取ります。 4.データに対して実行されているバックグラウンド分析ルーチンもあります。

上記のすべてのセットアップとシステムは、1台のAmazonEC2クラウドマシンにデプロイされます。このプロジェクトは現在、600を超えるデバイスと400のユーザーをサポートしています。しかし、デバイスの数が時間とともに増加するにつれて、サーバーのパフォーマンスは低下します。

このプロジェクトを拡張して、より多くのデバイスをサポートできるようにしたいと考えています。私の最初の考えは、現在のサーバーのようにもう1つのサーバーを作成し、これらの間でデバイスをサーバーに分割することです。しかし、ここでも、Django adminですが、中央のユーザーとデバイスの管理ポイントが必要です。

何か案は?スケーラブルなアーキテクチャを作成するための最良の方法は何ですか?可能であれば、Postgresクラスターを作成してDjangoで使用するにはどうすればよいですか?

3
user38827

あなたの質問は詳細が短く、手を振るのが長いですが、あなたの最初の考えはかなり健全なスタートであるように思えます。アプリは、基本的に同じ負荷分散アーキテクチャを使用してスケールアップするZenossモニタリングスイートと非常によく似ています。単一の管理インターフェースを備えたデータ収集ワークロードを共有する複数のモニタリングホストと、管理ホストまたは別のデータベースシステム。

ボトルネックがポイント#1(サーバーにデータを送信するデバイス)にある場合、それらのタスクを2番目のマシンに分割すると、負荷が増大する余地が生まれるはずです。実装上の最大の障害は、通常、複数のDjangoサーバー間でタスクを管理する方法です。分散タスクキューエンジンであるCeleryは、現時点でおそらく最良のオプションです。元々はDjangoを中心に設計されていました。あなたにとって良いことであり、開発者とユーザーの非常に活発で役立つコミュニティがあります。

ただし、ポイント#2と#4が現在の制限である場合は、おそらくデータベースのスケーラビリティについて話していることになります。これは一般的に難しい問題です。データベース容量をスケールアップするための、コード透過的で負荷に中立で安価な方法はありません。

より多くのデータベースの「読み取り」を取得する必要があるだけの場合IO容量、レプリケーションでうまくいく可能性があります。PostgresはSlony-Iと呼ばれる外部ツールを使用したレプリケーションをサポートしています。これはシングルマスターレプリケーションです。マスターで実行されたステートメントのフィードコピーを取得する複数の読み取り専用「スレーブ」ホスト。アプリのすべての書き込み(UPDATE、INSERT、DELETE ...)は単一のマスターホストを経由しますが、読み取りは分散します(SELECT。。 。)マスターとすべてのスレーブにまたがって。

分散読み取りに必要なコード変更は、通常、非常に簡単です。 Django最近、複製されたデータベースのサポートが追加されました。これは私が使用したことはありませんが、かなり良いはずです。

より多くのデータベース書き込みが必要な場合IO容量、シャーディングはおそらく機能します。各ホストは各データベーステーブルの個別の一意のチャンクを保持します。DBクライアントは決定論的関数を使用して、特定のレコードが存在する場所を決定します、したがって、負荷分散は事実上ステートレスであり、膨大な数のDBサーバーにスケールアップできます。Djangoの新しいマルチデータベースサポート(上記と同じリンク)もシャーディングをサポートします。コードの変更が必要になるため、痛みを抑える必要があります。

また、今日、インターネット上のほぼすべての高度にスケーラブルなWebアプリケーション(Facebook、Google、Twitter ...)の一部であると思われるMemcachedについても触れておきたいと思います。優れたキャッシュ実装は、高価で低速なDBルックアップを安価で高速なキャッシュルックアップに変換することにより、データベース要件を元のサイズの何分の1かに削減できます。 Djangoは、かなり前からMemcached統合をサポートしてきました。

私はこれのどれもあまり具体的ではないことを理解していますが、それはあなたに詳細を理解するためのかなり良い出発点を与えるはずです。あなたのプロジェクトで頑張ってください。

4
Ryan B. Lynch

最初にあなたは気づかなければなりません、あなたのボテルネックはどこにありますか?アプリケーション層の問題?データ層へのアクセス?アクセスパターンは何ですか?主に読む?それとも主に書き込みますか?

アプリケーション層の場合:

  • アプリケーションサーバーの追加
  • 一部のアクションは、ユーザーが終了を待たずにジョブキューに入れることができます(デバイスへのコマンドなど)。

データレイヤーの場合、次の方法があります。

  • あなたの仕事量について考えますか?いくつかのクエリを減らすことができますか?スキーマを変更できますか?おそらく、いくつかの非正規化を追加します(統計の事前計算、データの集計)。非常に大きなテーブルの場合、おそらく垂直分割を追加できます
  • 読み取りスケーリングには、Ryan B.Lynchのようにレプリケーションを使用できます。
  • Memcachedまたは同様のものを使用したキャッシング。ただし、覚えておいてください: "コンピュータサイエンスには、キャッシュの無効化と名前の付け方という2つの難しいことがあります。"
  • シャーディングされたデータベースの管理は面倒なので、シャーディング(水平分割)はお勧めしません。 ここに素敵な記事があります シャーディングについて。
  • データを異なるデータバックエンドに分割します。 ここに素敵な記事があります アイデアを説明します。
0
sumar