Skip to content
所有文章
工程 · 4 min read

從面試的一句話,到追出一個 cache 迴圈

同一個網域、同樣的 TTL,HTML 離開 CDN edge 的比例卻是圖片的 17 倍。這個系列從一個 HTTP request 開始,一路追到 load balancer 後面的 cache 迴圈。

CDN cache 系列的脈絡圖:一個 request 經過 Akamai、load balancer 和兩條 LB cache 路線,以及 proxy 路線上的 refresh 迴圈

我以為 CDN 是一個方塊。追完這個問題,我才知道它是一條鏈。

故事

我原本只懂系統設計面試程度的 CDN:「加一層 CDN,使用者載入就會變快」。

後來我看 CDN 的報表,發現一件怪事。同一個網域、同樣的 TTL,HTML 離開 edge 的比例卻是圖片的 17 倍。追下去,我發現有一整條路線的檔案常常不留在 cache 裡。這條路線依副檔名收 html、css、js,其中大型 HTML 最嚴重。

為了搞懂原因,我從「一個 request 是什麼」開始往下挖。這個系列照我學的順序寫,每一篇都是我在追查途中補上的一塊。

先認識幾個詞

整個系列用同一個比喻:一家連鎖店,有一個中央倉庫和很多分店。

名詞白話解釋比喻
Request瀏覽器向伺服器要一個檔案顧客來店裡點一樣東西
Header附在 request 或回應上的小標籤訂單上的備註欄
Origin檔案真正存放的伺服器中央倉庫
Cache先存一份副本,下次直接拿分店貨架上的存貨
Edge server離使用者很近、存著副本的伺服器你家附近的分店
CDN一大群 edge server 組成的網路整個連鎖分店系統
Load balancerorigin 的入口,把 request 分給後面不同的機器倉庫門口的分貨員
Proxy站在中間,幫忙拿檔案再轉交的程式幫你跑腿去倉庫拿貨的人
Bypass header叫 cache「不要用你的副本」的標籤備註寫「請直接去倉庫拿新貨」

顧客向附近分店要東西,分店沒貨才回中央倉庫。這個故事的問題是:倉庫門口還有一個隱藏的小貨架,而且它看不懂備註。

路線圖

問題:「為什麼 HTML 的 cache 命中率比圖片差這麼多?」 1 基礎01020304 2 名詞與 header0506 3 Akamai0708 4 我以為的架構09101112 5 追查問題1314151617 6 我學到的18
一個問題分成六個階段、18 篇文章,從基礎依序讀到心得。

為什麼會這樣:三個條件交叉

proxy 路線的 LB cache 不讀 bypass header ×LB cache 過期後先回舊副本(stale-while-revalidate) ×proxy 對 HEAD refresh 回 405 =副本永遠過期,Akamai 每份副本只新鮮 1 秒
三個條件單獨看都很小,交叉起來就讓 Akamai 上的副本永遠過期。
  1. Bypass header 只在有規則的地方有效:bucket 路線的 LB cache 會讓路,proxy 路線的不會(Bypass header 只在有規則的地方有效)。
  2. 舊副本照樣往前送:LB cache 過期後先回舊檔,副本帶著很大的 Age 到達 Akamai(Stale-while-revalidate:先回舊檔,背景再刷新)。
  3. Refresh 永遠失敗:LB cache 用 HEAD 做 refresh,proxy 只接受 GET(Proxy 不接受 HEAD,刷新永遠失敗)。

三個條件各自都不嚴重。接在一起,每個大型 HTML 的 request 都跑回 origin(五個零件串成一個迴圈)。

我學到的

我現在會跟著一個 request 走完整條路。每到一層,我都會問三個問題:這裡有沒有 cache?它讀哪些 header?purge 清得到它嗎?(我學到的:cache 不是一個方塊,是一條鏈)

加一層 CDN 會變快。但要知道 request 停在哪一層,你得一層一層走過去。

參考來源:ByteByteGo: How does CDN work, RFC 9111: HTTP Caching, RFC 5861: stale-while-revalidate

↑↓ 移動 ↵ 開啟 esc 關閉