2011-08-15 11 views
0

ファイル(PDFファイルのページをイメージとして扱う)用のアプリケーションがあり、元のPDFファイルはS3に保存され、サーバーにダウンロードされますクライアントがそのうちの1つに当たるとイメージを生成します。これらのマシンには、各PDFファイルが1回だけダウンロードされることを保証するローカルキャッシュメカニズムがあります。特定のリソースパスに基づいて可能な限り負荷分散を実行する方法

クライアントがリクエストを受け取ったとき私にpdf 123.pdfのページを渡してください。このキャッシュがチェックされています。そこにpdfファイルがない場合、S3からダウンロードされてローカルキャッシュに保存されます。プロセスはこのページ1を生成し、イメージをクライアントに送り返す。

クライアント自体は特別なサーバーに接続されていることを知らないため、ウェブサイトサーバーにアクセスしているように見えますが、パフォーマンスのためにこのクライアントが常に指示されるようにしたい最初のリクエストを処理した同じファイルサーバー(およびS3からファイルをダウンロードしたもの)。

クライアントにCookieを設定するだけで、特定のファイルサーバーから常にダウンロードすることができますが、これをクライアントに配置すると、不当な使用につながることがあります。一部のユーザーは多くのドキュメントを開きますが、この負荷分散をリソースレベル(PDFドキュメント)で実行したいと思います。

各ドキュメントには一意のID(データベース内の整数のプライマリキー)があり、私の最初の解決策はRedisを使用してドキュメントIDをキーとして保存していました。この値は現在このドキュメントがキャッシュされているサーバーマシンのホストであり、私はRedisを削除したい、あるいは他のどこかのキーを探す必要がない、これを実装する簡単な方法を探しています。

また、定義されたアルゴリズムやアイデアが、その場でファイルサーバーを追加できるようになるといいでしょう。

リソースに基づく親和性を備えたこの種のロードバランシングを実行する最良の方法は何でしょうか?

このアプリは、Ruby、java、Scalaを組み合わせたものです。

答えて

2

私はロードバランサで、次のアプローチを使用したい:

  • ストリップクエリとフラグメントの部分を除去するために要求されたリソースのURLを。
  • 取り除かれたURLをStringに変換し、ハッシュコードを取得します。
  • ハッシュコードを使用して、使用可能なサーバーの一覧からバックエンドサーバーを選択します。例えば

    String[] serverNames = ... 
    String serverName = serverNames[hash % serverNames.length]; 
    

これは、すべてのサーバー間で負荷を均等に広がり、常に同じサーバーに同じ要求を送信します。サーバーを追加すると、キャッシュは自動的に調整されますが、キャッシングが再びウォームアップしている間にパフォーマンスが低下します。

「公平」を目指したいとは思わない。すなわち、各要求がおおよそ同じ時間を要するという何らかの種類の保証である。公平性を達成するには、各バックエンドの負荷を積極的に監視し、負荷に応じてディスパッチする必要があります。これはキャッシング/アフィニティを無効にする(やや)ことになり、測定と負荷分散の意思決定を行うためのリソースを消費することになります。ダム負荷分散アプローチ(例えば、私の提案)は、ユースケース全体のスループットを全体的に向上させるはずです。

関連する問題