現今的網頁架構相較於過往偏向靜態的形式已經變得複雜許多,大部分資料都要靠動態抓取,而抓取資料的過程就會產生許多 Request 請求去取得 Response ,不管是 client 端對 API 的 Ajax 操作,或是 server 端對資料庫的 query 都是類似的形式,而抓取資料的過程是需要時間的:client call API 後要等待 API response、backend 下 DB query 後也要等待資料庫查詢結果回傳,而當這樣的請求ㄧ多,例如高並發的狀況,是很有可能對服務的性能造成影響的,為了解決這個困境,就需要本篇文章的主角隆重登場了,那就是快取 (Cache)。
首先讓我們先思考一下前言的問題,如果一直去發出網路請求或是 DB query 會造成性能影響的話,你想到最直覺的解決方式會是什麼?
那就不要發出網路請求或 DB query啊!
咦,講幹話嗎,怎麼聽起來跟「吃飯會花錢怎麼辦?那就不要吃飯啊!」一樣無理。不過看似無濟於事的一個方式,卻是快取的核心概念。快取的概念其實就是提供一個額外的儲存空間,將可能需要透過請求得到的資料放在裡面,當之後要再請求資料時,先別急著發出請求,先問問快取它有沒有你要的資料吧,有的話很好,那你資料直接跟快取拿就好,也就省略了真的發出 request 的步驟,取得資料的速度也理所當然會提升,如果快取沒有你要的資料,再發出 request 去取得。而通常適合被快取的資料有兩項特性:
其實快取一開始出現時是在指 OS 方面的機制,透過快取 ,CPU 可以不必一直到 main memory 去拿資料,從而減少性能的耗損,後來這個概念被運用到了 OS 層以外的地方,以下就來介紹常見的幾種非 OS 層的快取形式:
client cache 所指的是伺服器與瀏覽器之間的快取機制,假設今天你是一個電商平台的開發者,而你們的商品大概每過幾個月才會更換一次,而看過電商網站就知道,賣東西是需要圖片來吸引消費者的,也就是說你的網站被瀏覽時,得透過 HTTP request 去下載上百張圖片,問題在於每次瀏覽都得重新下載一次所有圖片,但剛剛也說了,這些圖片可能幾個月才會更換,重複下載相同內容是浪費效能的一件事,於是我們可以把圖片存在瀏覽器的快取中,這樣除了第一次瀏覽網站要下載外,之後就可以直接去快取拿了。
client cache 的設定方式是透過 HTTP response header 去帶參數,browser 接收到後就會做對應的快取處理,詳細一點的介紹我推薦可以看胡立大大的文章,寫的非常仔細與易懂。
透過簡單的範例解釋一下快取流程,當 browser 第一次發送請求要取得 main.css 檔案時,server 在回傳的 response 帶入 Cache-Control 的資訊,並指定這個 cache 最大的生存時間為 604800 秒,browser 收到 response 後,將 main.css 放到瀏覽器快取中,之後在該 cache 生存時間內對於 main.css 的請求,就可以直接去 cache 取得檔案。
另一種方式是能透過 client 與 server 合作判斷檔案是否有受到更改,沒有更改的話可以直接取得快取的版本,關於 Last-Modified 與 If-Modified-Since 的介紹一樣建議看胡立大的文章,這邊就不細講了。
要知道距離不僅僅是愛情的毒藥(誤),也是影響 response time 的重大因素。
假設你身在台灣,跟一個架設在台灣的 server 取資料,花費的時間只要 500 ms,但如果去跟一個架設在美國的 server 取相同的資料,這時候的 response time 可能就增長為 3000 ms。
而 Networking cache 的概念即是我們常常聽到的 CDN (Content Delivery Network)。
為了避免取資源時都要跟距離遙遠的 server 溝通,造成效能的耗損,這邊也可以運用到快取的概念來優化它,既然跟距離遙遠的 server 溝通效能會比較低,那就盡量避免這件事的發生。於是我們可以在離 request 方近一點的地方建立 CDN,儘管第一次發送 request 仍要跟位於美國的 server 溝通,但拿到資料後就可以存放在比較接近我們的 CDN 快取中,未來要取資料,若快取還沒到期,就直接到 CDN 去取就可以了。
關於 networking cache ,我建議可以參考這篇文章,話說馬克大的系列文真的太精彩了,只能推爆。
今天簡單介紹了快取的觀念與 client cache , networking cache 兩種快取,明天將介紹另一種 cache - Application Cache。
結果其中一個團隊成員還有左手邊的同事都挑戰失敗了QQ
剩下我右手邊的同事一起奮鬥惹
想盡辦法當好一個Junior Backend Developer