LOG IN SIGN UP
Documentation

シールディング

Fastly のシールディング・サービスを使用すれば、特定の POP をオリジンのシールドノードとして指定することができます。指定後はオリジンへのすべてのリクエストがそのデータセンターを経由するので、一定のリソースに対してヒットする確率が高まります。別の POP に特定のオブジェクトがない場合は、その POP がオリジンに代わってシールドにクエリを行います (その POP がメンテナンスのためにダウンしていない場合)。

シールディングのしくみ

ユーザーが顧客のサーバに新しいコンテンツをリクエストし、そのコンテンツがこれまで Fastly のいずれかのどの POP にもキャッシュされたことがない場合、シールディングが有効になっているかどうかでリクエストの処理に生じる違いを以下に説明します。

シールディングが有効になっていない場合

まず、コンテンツへの最初のリクエストが POP A に届いたときに、シールディングが有効になっていない場合を考えます。このとき、POP にはコンテンツがキャッシュされていません。POP は、顧客のオリジンサーバにリクエストを渡すことで、コンテンツを取得します。POP A は取得したコンテンツをキャッシュし、それをユーザーに送信します。

caching behavior on the first request, without shielding enabled

同じコンテンツに対する 2 回目のリクエストが POP A に届いたときには、そのコンテンツはすでにキャッシュされています。この場合、リクエストは顧客のオリジンサーバには送られません。コンテンツがキャッシュされたコピーから送信されるだけです。

caching behavior on subsequent requests, without shielding enabled

しかし、2 回目のリクエストが POP A ではなく POP B に届いた場合、そのリクエストは再度顧客のオリジンサーバに渡されます。これによってコンテンツがキャッシュされて再度ユーザーに送られます。これは、対象コンテンツが POP A に対して最初にリクエストされた場合と同じです。

シールディングが有効になっている場合

コンテンツへの最初のリクエストが POP A に届いたとき、シールドが有効になっている場合を考えます。このとき、POP にはコンテンツがキャッシュされていません。リクエストはシールド POP に送られますが、この POP にもコンテンツはキャッシュされていません。シールド POP は顧客のオリジンサーバにリクエストを送ります。シールド POP は取得したコンテンツをキャッシュしてそれを POP A に送り、さらに POP A はそれをユーザーに送ります。

caching behavior on the first request, with shielding enabled

同じコンテンツに対する 2 回目のリクエストが POP A に届いたときには、そのコンテンツはすでにキャッシュされているので、シールド POP や顧客のオリジンサーバにリクエストが送られることはありません。

caching behavior on subsequent requests, with shielding enabled

しかし、2 回目のリクエストが POP A ではなく POP B に届いた場合、そのリクエストはシールド POP に送られます。シールド POP は、POP A への最初のリクエストによってすでにキャッシュのコピーを持っています。したがって、シールド POP のコピーの期限が切れるまで、そのコンテンツへのリクエストが顧客のオリジンサーバに送られることはありません。

シールディングを有効にする

シールディングは以下の手順に従って有効にします。

  1. シールディングを有効にした場合の組織への影響や潜在的な危険の詳細については、後出のシールディングに関する注意点をお読みください。
  2. Fastly アプリケーションにログインして configure ボタン (レンチ・アイコン)をクリックします。
  3. Service メニューからシールディングを有効にする Service を選択し、Service 名の右側にある青色の Configure ボタン (ギア・アイコン) をクリックします。

    the Configure button on a test service

  4. 左側にあるメニューから Hosts をクリックします。

  5. Backends エリアで該当するバックエンドの右側にあるギアのアイコンをクリックして、メニューから Edit を選択します。

    the Edit button on the backends menu

    Edit Backend ウィンドウが開きます。

    the Edit Backend window

  6. Shielding メニューから、シールドとして使用するデータセンターを選択し、青色の Update ボタンをクリックして変更を保存します。

  7. デフォルトのホストを変更した場合や、ホストを変更するためにヘッダを追加した場合は、変更したホスト名をドメインのリストに追加してください。

    リストに加えるには、まず左側のメニューの Domains をクリックし、当該のホストがページの Domains セクションに表示されているかどうかを確認します。表示されていない場合は New ボタンを使って追加します。

    the Domains area

    シールディングが有効になっている場合は、他の POP からのクエリがシールドへのリクエストとして処理されます。変更されたホスト名に関する情報がシールドにないと、シールドは、リクエストをどの Service にマッチするかを判断できません。ドメインリストにオリジンのホスト名を追加すれば、このような心配はなくなります。

  8. シールディングは、新しいバージョンの Service をデプロイすると有効になります。

シールディングに関する注意点

シールディングはトラフィックとヒット率だけでなく、設定とパフォーマンスにも影響を与えます。シールディングを設定する場合は、以下の点に注意してください。

トラフィックとヒット率に関する注意点

シールドへのトラフィックは、リモート POP へのリクエストを含め、通常トラフィックとして請求されます。 シールディングを有効にすると追加分の bandwidth 費用が発生しますが、これはオリジンの bandwidth (およびオリジンサーバの負荷) が減少することによって相殺されます。転送されるリクエストは直接オリジンには送られず、最初にシールドを経由します。

グローバルヒット率の計算値は、実際の数値より低くなることがあります。 グローバルヒット率の計算時にシールディングは考慮されません。エッジノードのキャッシュ内にオブジェクトがない場合は、ミスとして報告されます。バックエンドへのコールがなくても、ローカルミス / シールドヒットはミスとして報告され、統計データではヒットとなります。この場合、エッジノードからシールドへのリクエストも 1 回となります。ローカルミス / シールドミス時のリクエストは 2 回になります。これは、オリジンから後でリソースを取得するからです。シールディング時のキャッシュの詳細については、シールディングにおけるキャッシュヒットとキャッシュミスについてを参照してください。

設定に関する注意点

VCL を使用して手動でバックエンドを定義することはできません。 このレベルでのシールディングは、ユーザインタフェースまたは API を通じて実際のオブジェクトとして定義されるバックエンドに完全に依存しています。その他のカスタム VCL は問題なく機能します。

ユーザインタフェースを通じて自動ロードバランシングが選択されている場合、設定できるシールドは合計 1 つだけです。 自動ロードバランシングを選択した場合、選択できるシールドは合計 1 つだけです。自動ロードバランシングが設定されているときに複数のシールドを使用するには、カスタム VCL を使う必要があります。

スティッキー・ロードバランサとシールディングを同時に有効にするには、カスタム VCL が必要です。スティッキー・ロードバランサは、client.identity を使用してセッションの転送先を選択します。client.identity のデフォルトの転送先は IP リクエストヘッダです。通常の状況ではこれで問題ありませんが、シールディングを有効にすると、IP は、クライアントの IP ではなく送信元の POP の IP になります。したがって、シールディングとカスタムのスティッキー・ロードバランサを有効にするには、以下のようなスクリプトを使用する必要があります。

if (req.http.fastly-ff) {
  set client.identity = req.http.Fastly-Client-IP;
}

パフォーマンスに関する注意点

シールドに達する前に Host ヘッダを変更するときは、注意が必要です。 Fastly は Host ヘッダを使ってリクエストをマッチします。Host ヘッダが Service 内のドメインと一致しない場合は、404 エラーが発生すると考えられます。また、Host ヘッダを別の Service 内に存在するドメインに変更すると、パージの競合が発生する恐れがあります。

例えば、Service A のホスト名が a.example.com で、Service B のホスト名が b.example.com だとします。Service B が Host ヘッダを a.example.com に変更したとすると、エッジはそのリクエストが Service B のものだと判断しますが、シールドは Service A のものだと判断します。

ここで、Service A ではなく Service B のオブジェクトをパージした場合、シールドは、パージしたかった古いオブジェクトをエッジに返します。これは、パージが Service A ではなく Service B に対して行われたからです。Service A と Service B の両方のオブジェクトをパージしたいところですが、これは混乱とエラーを招く結果となります。

VCL は 2 回実行されます。シールドノードで 1 回実行され、エッジノードで再度実行されます。 berespresp に変更を加えると、シールドとエッジでの URL のキャッシュに影響する可能性があります。以下のような例を考えてみましょう。

例えば、オブジェクトを 1 時間 (3600秒) キャッシュしてブラウザに 10 秒間表示する、という処理を Fastly にさせたいとします。オリジンは、Cache-Control: max-age=3600 を送信します。ここで、beresp.http.Cache-Control の設定を取り消してから、Cache-Controlmax-age=10 に再設定します。シールディングが有効な場合、結果は期待どおりにはなりません。シールド上のオブジェクトには max-age=3600 が設定され、エッジには max-age=10 が伝えられます。

より優れたアプローチは、レスポンスヘッダの Surrogate-Control および Cache-Control を使用することです。Surrogate-ControlCache-Control よりも優先され、エッジノードを過ぎると削除されます。その上で、Cache-Controlmax-age がブラウザに届けられます。下記がレスポンスヘッダの例です。

Surrogate-Control: max-age=3600
Cache-Control: max-age=10

陥りやすいもう 1 つの落とし穴は、誤った Vary ヘッダをエッジ POP に送ることです。例えば、Cookie から特定の値を読み取り、その値をヘッダに追加し、そのヘッダを Vary ヘッダに追加するという VCL です。管理下にないキャッシュ (エンタープライズによく見られる共有プロキシなど) と最大限の互換性を得るには、Vary ヘッダを vcl_deliver で更新し、カスタム・ヘッダを Cookie に置き換えます。コードは次のようになります。

vcl_recv {
  # Set the custom header
  if (req.http.Cookie ~ "ABtesting=B") {
    set req.X-ABtesting = "B";
  } else {
    set req.X-ABtesting = "A";
  }
  ...
}

...

sub vcl_fetch {
  # Vary on the custom header
  if (beresp.http.Vary) {
    set beresp.http.Vary = beresp.http.Vary ", X-ABtesting";
  } else {
    set beresp.http.Vary = "X-ABtesting";
  }
  ...
}

...

sub vcl_deliver {
  # Hide the existence of the header from downstream
  if (resp.http.Vary) {
    set resp.http.Vary = regsub(resp.http.Vary, "X-ABtesting", "Cookie");
  }
}

ただし、上記のコードをシールディングと組み合わせると、エッジ POP で Vary ヘッダに Cookie が設定されるため、ヒット率が極端に低下します。これを回避するには、Fastly のキャッシュからのリクエストでない場合にのみ、VaryCookie が足されるように上記の VCL を修正します。Fastly-FF ヘッダは、それを指示するのに適しています。コードは次のようなものになります (上の例と同じ vcl_recv を含む)。

# 上記のコード例と同じ vcl_recv です

sub vcl_fetch {
  # Vary on the custom header, don't add if shield POP already added
  if (beresp.http.Vary !~ "X-ABtesting") {
    if (beresp.http.Vary) {
      set beresp.http.Vary = beresp.http.Vary ", X-ABtesting";
    } else {
      set beresp.http.Vary = "X-ABtesting";
    }
  }
  ...
}

...

sub vcl_deliver {
  # Hide the existence of the header from downstream
  if (resp.http.Vary && !req.http.Fastly-FF) {
    set resp.http.Vary = regsub(resp.http.Vary, "X-ABtesting", "Cookie");
  }
}

Translations available [EN] English

翻訳についての注意事項