CDN 在靜態資源的加速場景中是將靜態資源緩存在距離客戶端較近的CDN 節點上,然后客戶端訪問該資源即可通過較短的鏈路直接從緩存中獲取資源,而避免再通過較長的鏈路回源獲取靜態資源。因此 CDN的緩存命中率的高低直接影響客戶體驗,而保證較高的命中率也成為了站長的核心命題。在本文中我們就一起探討 CDN 緩存命中率的概念、影響因素以及優化策略。
1、緩存命中率的概念
CDN 的緩存命中率包括兩種:字節緩存命中率和請求緩存命中率。其中字節緩存命中率是指 CDN 緩存命中 Response 的字節數除以 CDN所有請求 Response 的字節數。而請求緩存命中率是指 CDN 緩存命中的請求的個數除以 CDN 所有的請求數。
從上面的描述中可以查看到字節緩存命中率可以表征回源流量的大小,回源流量越高那么源站的流出流量也就越大,這樣對于源站的帶寬資源以及其他的負載都會越大,因此回源流量代表了源站服務器接收到的負載壓力。而我們在業務使用中也主要關心字節緩存命中率。
查看緩存命中率主要包括控制臺、 CDN 日志和 API/SDK 查看兩種方式。現在 CDN 控制臺上提供的命中率監控均是字節緩存命中率,如圖1 中所示即是控制臺監控信息中命中率的詳情。
????????????????????????????????????
????????????????????????????????????????????????????????????????????????圖 1. 控制臺命中率監控示意圖
在CDN的請求日志中,CDN記錄了所有的CDN請求的緩存命中狀態,詳細的日志格式請參考CDN日志格式,其中“cache命中狀態”字段為HIT即表示命中,而MISS即表示未命中的狀態。這里特別需要注意的一點是這里的命中狀態僅表征CDN的L1節點的命中狀態,當CDN的L1節點未命中緩存但是L2節點命中緩存的情況下這里仍然會顯示MISS。
而API/SDK的方式CDN分別提供了DescribeDomainHitRateData和DescribeDomainReqHitRateData兩個接口分別查詢的CDN的字節緩存命中率和請求緩存命中率。該接口是可以查看到歷史90天內的所有的數據。
2、影響因素及優化建議
CDN的緩存規則同時按照CDN上的緩存規則、源站配置的Cache-Control等response頭、文件類型等綜合考慮,具體的緩存規則解讀建議查閱【 CDN 最佳實踐】CDN 緩存策略解讀和配置策略。那么按照上述的緩存規則會影響命中率的因素主要有以下:
1. 文件類型是否適合于在CDN上緩存。
CDN在業務架構中負責加速靜態資源,因此如果動態資源也經過CDN的話是會導致CDN的命中率下降的。CDN判斷動態文件和靜態文件的標準是該文件的response頭中是否帶有Etag頭和Last-modified頭。這兩個頭在HTTP協議中分別通過文件內容和文件最后修改時間表征文件的修改情況。
因此建議用戶使用過程中優化點:
網站架構是否適合于動靜分離。動靜分離是常見的網站優化的策略,主要是通過將靜態資源和動態資源分離成兩個站點提供服務。靜態資源由于長時間不會發生變化,因此可以使用CDN加速;而動態資源因為需要實時獲取源站的資源并且可能源站加載需要一段時間(CDN回源獲取數據有嚴格的的回源超時時間,動態文件響應較慢可能導致CDN回源直接拋出504錯誤)而直接解析到源站服務器拉取資源。
靜態文件文件是否在response頭中返回Etag頭和Last-modified頭。在CDN上沒有配置緩存規則的情況下,靜態文件沒有返回Etag頭和Last-modified頭也同樣會導致該靜態資源不在CDN節點上緩存。如圖2中所示,x-swift-cachetime頭即表示該文件在CDN上的緩存時間(單位是秒)。該文件其實為靜態文件,但是由于response頭中沒有Etag和Last-modified導致CDN并不會該文件進行緩存。
????????????????????????????????????
????????????????????????????????????????????????????????????????????????圖 2. CDN 緩存時間示意圖
配置合理的源站緩存規則。源站服務器可以針對于資源配置其緩存規則。當源站配置了以下response頭時CDN將不會對該文件進行緩存:
????1)有s-maxage=0,no-cache,no-store,private其中一種
????2)如果沒有s-maxage或者s-maxage=0,并且有max-age=0.
????3)帶Pragma: no-cache
而且上述的response頭在CDN緩存規則中將有最高優先級(即使CDN上配置了緩存規則也不緩存),因此上述的這些response頭并不適合于配置于源站的靜態資源的。另外當CDN上沒有配置緩存規則時,資源的緩存規則將按照源站的Cache-Control或者Expires頭進行緩存(Cache-Control優先級比Expires高),因此建議用戶設置合理的Cache-Control或者Expires頭。
配置緩存規則。上面所指的沒有包括Etag和Last-modified頭而導致CDN緩存時間為0的場景是CDN控制臺上沒有配置緩存配置時會出現這種情況,因此如果用戶的靜態資源確實無法配置上述兩個response頭的話是可以考慮針對該文件配置緩存規則,這樣該文件即可在CDN上按照緩存規則進行緩存。
2. CDN的刷新和預熱功能
CDN提供了刷新緩存和預熱緩存兩個操作。兩個操作都會對緩存命中率有影響,但是兩個操作的影響是完全相反的。因此用戶是需要了解兩個操作的概念以及使用場景。
刷新功能是指將特定URL或者目錄下的所有歷史緩存的內容清除掉,該操作常用于源站進行同名更新后導致CDN緩存內容已為歷史臟數據,刷新后將使URL下次訪問時直接回源。因此會導致命中率下降。
預熱功能是將URL提前上傳到CDN的L2節點上,這樣下次訪問的時候就不需要從源站再拉取資源了,因此預熱是沒有直接導致L1的命中率升高,但提升了CDN的真實命中率。
因此建議用戶使用過程中優化點:
慎重使用刷新功能。刷新功能肯定是會導致命中率出現下降的,特別是對于加速域名根目錄的刷新任務會導致加速域名下的所有緩存均無效,勢必會導致后續出現大量回源請求導致源站服務器負載升高。因此請用戶在實際線上環境特別是高峰期進行刷新操作。另外建議客戶盡量避免執行靜態資源同名更新,可以嘗試通過添加queryString的方式進行版本更替(例如url中帶有?version=1.1等方式)。
業務高峰前預熱熱門資源。預熱可以提前將資源預熱到CDN的L2節點,避免業務高峰對于源站產生壓力,也同時保證了CDN的真實命中率。但是預熱的請求次數每天客戶均是有條數限制的,因此建議客戶可以根據歷史的熱門資源統計得要待預熱的資源URL進行操作。
3. CDN緩存規則是否合理
CDN上是可以針對于目錄或者后綴名設置緩存配置的。而在CDN和源站同時配置緩存規則時是會以CDN上的緩存規則優先的(除非源站設置了不允許緩存的規則),因此建議用戶在CDN控制臺中設置合理的緩存規則,避免走默認的緩存規則導致頻繁回源(默認緩存經常緩存3600秒過期)。另外特別注意CDN控制臺上配置的緩存時間為0秒時該資源并不是客戶端直接請求到源站的,而是客戶端請求仍然會先到CDN節點,然后由CDN節點觸發回源請求到源站獲取資源,并且流出流量仍然會計算CDN的流出流量。
4. 可變參數導致命中率下降
客戶請求的URL中常帶有queryString,例如上面所說的請求URL中為了區分版本帶上?version=1.1等參數或者CDN回源到私有讀寫類型的bucket時會帶上OSS私有訪問需要的OSSAccessKeyId、Expires和Signature參數。在CDN處理的過程中默認的處理邏輯是對于同樣的URL而帶有不同queryString的請求會認為完全不同的請求,因此緩存也對應的是不同份,這就會導致如果queryString參數發生變化時會導致重新回源,因此命中率會出現下降的情況。
因此建議用戶使用過程中優化點:
業務系統允許的情況下使用“過濾參數”功能。開啟過濾參數功能后,CDN接收到queryString的URL替換成沒有帶參數的URL。例如請求URL為http://www.aliyun.com/1.jpg?version=1,開啟過濾參數后將替換URL為http://www.aliyun.com/1.jpg,這樣講查看是否存在有http://www.aliyun.com/1.jpg的緩存,如果有的話將直接返回客戶端;如果沒有緩存的話就會按照http://www.aliyun.com/1.jpg請求回源站。因此業務系統允許queryString不敏感的情況下可以開啟該功能。但是對于一些系統需要queryString進行傳參或者設置跳轉邏輯的話就不能開啟該功能。
對于CDN加速OSS的場景建議使用“私有bucket回源”功能。當OSS設置為私有時不可以開啟過濾參數并且當簽名querystring發生變化時還會影響CDN緩存命中率。而“私有bucket回源”功能將使CDN的請求回源OSS的時候自動帶上簽名querystring參數,而不需要客戶自己在請求CDN的時候設置。這樣即實現了OSS本身資源的安全防護而又不影響CDN的緩存命中率。
5. CDN加速域名流量較低
CDN節點作為所有使用CDN的用戶公用的節點資源,因此CDN配置的緩存規則表示了該資源在CDN上的緩存最長時間,如果用戶在CDN上的緩存資源的熱度較低的話是有可能被提前踢出CDN節點的緩存的。因此可以理解為緩存按照熱度屬性采取末尾淘汰制,所謂熱度就是該文件在該節點上被訪問的頻率,文件熱度不夠即被提前剔除。
因此建議用戶使用過程中優化點:
對于流量較低的域名可以提前定期將熱度資源預熱到CDN節點上,避免影響業務使用。
建議用戶考慮對于流量較低的域名可以不使用CDN加速,這樣的域名的加速效果并不明顯。