一覧CL-08-3 · ロードバランサーと配信

CDNのキャッシュとオリジン障害

配信できることと最新の版を返すことを分けて、保存期限・無効化・切替え先の更新状況を説明します。

説明

CDNは配信拠点に応答を保存し、オリジンへ毎回取りに行かずに返せます。そのため、オリジンを更新しても、期限内の保存版が配信される場合があります。障害時に古い版を許容するか、別オリジンへ切り替えるかも、内容の鮮度と合わせて考えます。

公開用の同じURLを、TTL60秒の一つの配信拠点で扱います。保存、更新、purge、オリジン停止、期限切れ、30秒だけのstale許容、予備オリジンへの切替えを順に確認します。時刻と原本の版を明示的に変更して結果を追います。

配信できることと最新の版を返すことを分けて、保存期限・無効化・切替え先の更新状況を説明します。

1最初の要求でオリジンから保存する

Edgeはprimaryとsecondaryにversion=1を持ち、最初の時刻は0、キャッシュは空です。この演習の応答は共有キャッシュで保存してよい公開コンテンツです。

from edge import Edge edge = Edge()同じ公開URLを扱う配信拠点を用意する edge.get()原本を取得して保存する

MISSでprimaryからversion=1を取り、expires=60になります。origin_calls=1はオリジン取得を試した回数です。

2原本の更新だけでは保存版は変わらない

primaryだけをversion=2へ更新し、同じURLを要求します。

edge.origins["primary"]["body"] = "version=2"primaryの内容だけを更新する edge.get()期限内の保存版を取得する

HITでversion=1です。origin_callsは1のままで、原本を取り直していません。更新対象がオリジンか、配信拠点の保存版かを確認します。

3purge後に新しい版を取得する

この配信拠点の保存版をpurgeしてから再取得します。

edge.purge()現在の拠点の保存版を無効にする edge.get()オリジンから新しい内容を取得する

MISSでversion=2となり、origin_calls=2です。実際のCDNでは複数拠点への無効化反映も確認対象ですが、ここでは一つの拠点の状態を追っています。

4オリジン停止中も期限内なら保存版を返す

primaryを停止状態にします。時刻はまだ0です。

edge.origins["primary"]["up"] = Falseprimaryを取得できない状態へ変える edge.get()期限内の保存版を使えるか確認する

HITでversion=2を返し、オリジン呼出しは増えません。期限内の保存版があることが、オリジン停止の影響を抑えています。

5期限が切れた場合の失敗

時刻を61へ進めます。最初は期限切れの応答を許可していません。

edge.clock = 61保存期限を過ぎる時刻へ進める edge.get()古い応答を許可しない場合の結果を確認する

期限60を過ぎ、primaryも取得できないため502です。キャッシュが存在することだけでは、任意に古い版を配信してよいことにはなりません。

6障害時に三十秒だけ古い応答を許可する

オリジン取得が失敗した場合に限り、期限後30秒までの保存版を許可する方針にします。

edge.stale_if_error = 30取得失敗時に期限後30秒まで許容する edge.get()許容範囲内の古い保存版を確認する

STALEでversion=2です。age=61、stale_seconds=1なので、期限後30秒の範囲に入っています。常に最新である必要がある内容へ無条件に使う方針ではありません。

7古い応答の許容範囲も超える

時刻を91へ進めます。

edge.clock = 91期限後30秒も超える時刻へ進める edge.get()許容上限後の結果を確認する

期限60から31秒過ぎたため、許容する30秒を超えて502になります。古い応答を許容する場合も、どこまで古くてよいかという上限があります。

8予備オリジンは古い版を持っている場合がある

secondaryへの切替えを有効にします。secondaryはまだversion=1です。

edge.fallback = True予備オリジンへの切替えを有効にする edge.get()予備側の保存時点を確認する

secondaryからversion=1を取得して配信できましたが、primaryのversion=2より古い内容です。切替えで利用可能になったことと、最新の内容になったことは別に確認します。

9主オリジンの復旧後も予備から取得したキャッシュが残る

primaryを復旧させて一度取得し、その後purgeして再取得します。

edge.origins["primary"]["up"] = Trueprimaryを復旧させる edge.get()予備から保存した版が残るか確認する edge.purge()古い保存版を無効にする edge.get()primaryの現在の内容を取り直す

復旧直後はHITでversion=1、purge後はprimaryからversion=2です。原本の復旧、配信拠点の保存版、無効化の反映を、それぞれ確認する必要があります。

まとめ

原本を更新しても、期限内の保存版が返る場合があります。

障害時の古い応答には、許可条件と古さの上限を決めます。

予備オリジンや復旧後の保存版が、どの時点の内容かを確認します。

操作履歴と解説を振り返れます。

Python 3

1
from edge import Edge edge = Edge() edge.get()
MISS source=primary body=version=1 expires=60 origin_calls=1
2
edge.origins["primary"]["body"] = "version=2" edge.get()
HIT body=version=1 age=0 origin_calls=1
3
edge.purge() edge.get()
MISS source=primary body=version=2 expires=60 origin_calls=2
4
edge.origins["primary"]["up"] = False edge.get()
HIT body=version=2 age=0 origin_calls=2
5
edge.clock = 61 edge.get()
ERROR status=502 origin unavailable; no permitted cached response
6
edge.stale_if_error = 30 edge.get()
STALE body=version=2 age=61 stale_seconds=1 origin_calls=4
7
edge.clock = 91 edge.get()
ERROR status=502 origin unavailable; no permitted cached response
8
edge.fallback = True edge.get()
MISS source=secondary body=version=1 expires=151 origin_calls=6
9
edge.origins["primary"]["up"] = True edge.get() edge.purge() edge.get()
HIT body=version=1 age=0 origin_calls=6
MISS source=primary body=version=2 expires=151 origin_calls=7

演習完了