はじめに
ロードバランサーにはスティッキーセッションという機能があります。
ユーザーのセッションを特定のインスタンスに固定する際に使用する機能で、メモリ内キャッシュを使用したり、セッションを使用した登録処理など、ロードバランサーの負荷分散機能を避け処理するインスタンスを固定させたい場合に使用します。
スティッキーセッションとは
スティッキーセッションはCookieを使用した機能です。
Application Load Balancer(以下ALB)とClassic Load Balancer(以下CLB)は、ロードバランサーがCookieを基にユーザーからのセッションを同じインスタンスに送信します。
Network Load Balancerは、送信元IPアドレスを使用し、送信元IPアドレスが同一である限り、同一のターゲットへリクエストを送信します。
本稿では、ALBとCLBのスティッキーセッションについて解説します。
スティッキーセッションCookieの種類
ALBとCLBのスティッキーセッションで使用するCookieには、期間ベースとアプリケーションベースの2種類があります。
期間ベースではロードバランサーが生成するCookieのみを使用し、アプリケーションベースではアプリケーションとロードバランサーが生成するCookieの両方を使用します。
期間ベースのスティッキーセッション
期間ベースのCookieを使用したスティッキーセッション機能では、ロードバランサーがCookieを生成します。
Cookieの更新
ALBの場合は、アクセスする度にALBがCookieの値を更新し、有効期限もその度に延長されますが、CLBでは、Cookieの値も有効期限も更新されません。
リクエスト毎のレスポンスヘッダーでは、ALBはリクエストの度にSet-Cookieされていますが、CLBの場合は、初回アクセスなど、ALBのCookieがない場合のみSet-Cookieされ、それ以外ではSet-Cookieされません。
CLBが生成するCookie
CLBが生成するCookieの値には特徴があります。
例えば2台のインスタンスAとBがあるとします。
インスタンスAにルーティングする場合と、インスタンスBにルーティングする場合のCookieの値は当然異なりますが、Cookieを削除したり、新規セッションでアクセスした場合、インスタンスAに再度ルーティングされる際に生成されるCookieの値は、前回Aにルーティングされた際に生成された値と全く同一です。
Bの時も同様に、再度ルーティングされてもCookieの値は以前と変わりがありません。
一方で、ALBは、前述のとおりリクエスト毎にSet-Cookieされますので、Cookieが削除されたとしても、同じインスタンスに再びルーティングする場合のCookieの値は常に違います。
リクエストをバインドする仕組み
ロードバランサーがクライアントから最初にリクエストを受信すると、独自のアルゴリズムに基づきリクエストをインスタンスにルーティングします。
その際、ALBは「AWSALB」、CLBは「AWSELB」という名前のCookieを生成します。
生成されたCookieの値には、後続のリクエストを初回にルーティングしたインスタンスに固定するための情報が含まれています。
ルーティングする対象のインスタンスに障害が発生したり、Cookieの値を複合化できない場合や、対象インスタンスの情報が取得できない場合などは、初回アクセス時と同じようにアルゴリズムに基づいて正常なインスタンスにルーティングし、スティッキーセッションのCookieはSet-Cookieし直されます。
アプリケーションベースのスティッキーセッション
スティッキーセッションを設定する際に、アプリケーションで生成される任意のCookie名を指定します。
ALBの場合は、ターゲットグループごとに Cookie名を個別に指定する必要があります。
Cookieの更新
期間ベースのCookie同様、ALBでは、ロードバランサーが生成するCookieの有効期限がリセットされますが、CLBはリクエスト毎に更新されません。
リクエストをバインドする仕組み
ロードバランサーはクライアントからのリクエストをインスタンスに送信し、レスポンスを受け取る際に、指定されたアプリケーションのCookieがあるかをチェックします。
アプリケーションCookieがあれば、それとは別のCookieをロードバランサー自身が生成し、クライアント側に両方のCookieを返します。
ロードバランサーが生成するCookieには、リクエストを送信したインスタンスについての情報が含まれています。
次のリクエストでは、ロードバランサーは指定されたCookieとロードバランサーが生成したCookieの両方があれば、最初に送信したインスタンスへリクエストを送信します。
さいごに
スティッキーセッションは、送信先のインスタンスを固定するために有効な機能ですが、負荷分散の恩恵を受けられないため、特定のインスタンスのみ負荷が高まるという状況が起きる可能性があります。
スティッキーセッションを使用する際は、このリスクをしっかり理解するとともに、セッション情報などをインスタンス自身に持たせない、ステートレスな構成にすることも一度検討してみてはいかがでしょうか。
参考
Elastic Load Balancing
Configure sticky sessions for your Classic Load Balancer - Elastic Load Balancing
Network Load Balancers のターゲットグループ - Elastic Load Balancing