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
from edge import Edge
edge = Edge()
edge.get()MISS source=primary body=version=1 expires=60 origin_calls=1
edge.origins["primary"]["body"] = "version=2"
edge.get()HIT body=version=1 age=0 origin_calls=1
edge.purge()
edge.get()MISS source=primary body=version=2 expires=60 origin_calls=2
edge.origins["primary"]["up"] = False
edge.get()HIT body=version=2 age=0 origin_calls=2
edge.clock = 61
edge.get()ERROR status=502 origin unavailable; no permitted cached response
edge.stale_if_error = 30
edge.get()STALE body=version=2 age=61 stale_seconds=1 origin_calls=4
edge.clock = 91
edge.get()ERROR status=502 origin unavailable; no permitted cached response
edge.fallback = True
edge.get()MISS source=secondary body=version=1 expires=151 origin_calls=6
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
演習完了