web-dev-qa-db-ja.com

複数のWebサーバー間でセッションスティッキをどのように実現しますか?

StackOverflow/ServerFaultにはいくつのWebサーバーがありますか?

答えが「複数」である場合、DNSポーリング中に Session Stickiness を達成していますか?

22
Shore

大規模なWebサイトは、複数のマシン間で「負荷分散」される場合があります。多くの負荷分散設定では、ユーザーはセッション中に任意のバックエンドマシンにアクセスする可能性があります。このため、多くのマシンがユーザーセッションを共有できるようにする方法はいくつかあります。

選択する方法は、使用する負荷分散のスタイル、およびバックエンドストレージの可用性/容量によって異なります。

Cookieのみに保存されるセッション情報:セッション情報(単なるセッションIDではない)は、ユーザーのCookieに保存されます。たとえば、ユーザーのCookieに買い物かごの内容が含まれている場合があります。ユーザーがセッションデータを改ざんしないようにするために、HMACがCookieとともに提供される場合があります。この方法は、ほとんどのアプリケーションにおそらく最も適していません。

  • バックエンドストレージは不要
  • ユーザーは毎回同じマシンにアクセスする必要がないため、DNSロードバランシングを使用できます。
  • データベースマシンからのセッション情報の取得に関連する待ち時間はありません(HTTPリクエストで提供されるため)。サイトが異なる大陸のマシンによって負荷分散されている場合に役立ちます。
  • セッションに保存できるデータの量は制限されています(4K Cookieのサイズ制限により)
  • ユーザーがセッションの内容を見ることができないようにする必要がある場合は、暗号化を採用する必要があります
  • ユーザーによるセッションデータの改ざんを防ぐために、HMAC(または同様のもの)を使用する必要があります
  • セッションデータはサーバー側に保存されないため、開発者がデバッグするのはより困難です。

ロードバランサーは常にユーザーを同じマシンに誘導します:多くのロードバランサーはセッションCookieを設定して、ユーザーがリクエストを行っているバックエンドマシンを示し、それらを将来そのマシンに誘導します。ユーザーは常に同じマシンに誘導されるため、複数のマシン間でセッションを共有する必要はありません。これはいくつかの状況で良いかもしれません:

  • 既存のアプリケーションのセッション処理は、複数のマシンに対応するために変更する必要がない場合があります
  • セッションを格納するために共有データベースシステム(または類似のシステム)は必要ありませんが、信頼性は向上しますが、複雑さが犠牲になります。
  • ダウンしているバックエンドマシンは、そのマシン上で開始されたユーザーセッションをすべて停止します。
  • 機械を使用不能にすることはより困難です。マシン上でメンテナンスのために停止するセッションを使用しているユーザーは、マシンの電源を切る前にタスクを完了できるようにする必要があります。これをサポートするために、ウェブロードバランサーには、特定のバックエンドマシンへのリクエストを「排出」する機能があります。

共有バックエンドデータベースまたはキー/値ストア:セッション情報はバックエンドデータベースに格納され、すべてのWebサーバーがクエリと更新にアクセスできます。ユーザーのブラウザは、セッション情報を指す識別子(セッションIDなど)を含むCookieを保存します。これはおそらく3つの方法の中で最もクリーンな方法です。

  • ユーザーは、保存されたセッション情報にさらされる必要はありません。
  • ユーザーは毎回同じマシンにアクセスする必要がないため、DNSロードバランシングを使用できます。
  • 欠点の1つは、使用するバックエンドストレージシステムにボトルネックが生じる可能性があることです。
  • セッション情報が期限切れになり、一貫してバックアップされる場合があります。

全体として、ほとんどの動的Webアプリケーションはいくつかのデータベースクエリまたはキー/値ストア要求を実行するため、データベースまたはキー/値ストアはセッションデータの論理的な格納場所です。

42
Tommeh

複数のフロントエンドWebサーバー間でセッションを維持する方法が質問である場合、答えは通常、集中型データベースを使用することです。ローカルファイルシステムのセッションファイルを追跡するためにWebサーバーインスタンスに依存する代わりに、セッションIDとデータを中央DBに書き込み、すべてのWebサーバーがそこからデータを取得します。

4
zombat

@David Pashleyが言及していないように、nemcachedを使用することは良い解決策のようです

つまり、リモートmemcachedインスタンスをすべてのサーバーで共有し、独自のセッションハンドラーを提供するmemcache PECL拡張機能を使用します。

Php設定で2つのパラメーターを変更するだけです!

これは良いチュートリアルです http://www.dotdeb.org/2008/08/25/storing-your-php-sessions-using-memcached/

1
Tristan

IIRCは、DotNetRocks#440で1サーバー期間と述べました。それがまだ当てはまるかどうかわからない。

編集:実際には Hanselminutes#134 でした。ごめんなさい。

0
Donald Byrd

クッキーを設定できます。

リモートIPのハッシュを計算できます(最も単純な奇数番号のリモートホストはサーバーAに行き、偶数番号のホストはサーバーBに行きます)。

Sslトンネルを使用している場合は、ソースシステムに残っているいくつかの値を使用してそれを行うこともできるようです。

通常、上記の各メカニズムには、「リバースプロキシ」サーバーまたはなんらかのロードバランサーが必要です。そのロードバランサーはトラフィックを受け入れ、上記の基準のいずれかに基づいて、最初にセッションを持っていたサーバーにトラフィックを転送します。

「DNSポーリング」の意味がわかりません

0
chris

a)セッション情報をユーザーCookieに保存できます。サーバー側にデータを保存せず、セッション状態を保持するステートレスの強化されたCookieを参照してください http://www.cl.cam.ac.uk/~sjm217/papers/protocols08cookies.pdf 。 b)セッションバックエンドストレージをデータベースまたはmemcachedに変更できます。単一障害点を排除するために、データベース複製または複数のmemcachedノードを設定できます。 memcachedは、セッションでのユーザー状態の損失が大きなエラーではなく、ユーザーを不満にしないようなセットアップで推奨されることに注意してください。状態の保持が重要な場合は、データベースを使用してください。 PHP、DjangoおよびRailsの両方を使用すると、開発者はカスタムセッションバックエンドを作成できます。

0
Kristaps