如果你去超市買過牛奶,那你就能理解服務端和客戶端快取!
如果你是一個網際網路使用者,那你一直受益於快取!但是,你可能不知道它何時以何種形式發揮作用。
從開發人員的角度看,快取是構建高效能應用和服務的必要手段。通過實現快取,開發者能更好地處理海量請求。也許快取優化的效果只有 1 ~ 2s 的區別,差異微乎其微。但如果你想要處理海量使用者的請求,這是必要的!
我曾經做過一個網路應用程式,使我對快取的理解更加深刻。僅通過專業術語可能很難明白快取的含義,所以本文我將通過牛奶的生產線來幫助理解快取的概念。在理解本文之前,你需要了解 web 伺服器。不懂的童鞋可以通過連結瞭解。
沒有快取,網際網路會是什麼樣?
在我們聊快取之前,想象一下沒有快取的網際網路會是什麼樣的?假如你生活在18或19世紀的農村,你擁有一個農場——沒有冷藏技術。農場裡有幾頭奶牛,產出的牛奶會因為變質而變得沒有價值。(補充一下:有趣的是有些地方現在仍然沒有冷藏技術,他們直接喝牛乳,或者伴著穀物發酵後再喝。)
你要將牛奶賣給同鄉的小夥伴,會面臨三個問題:
- 喝牛奶的時間非常有限。
- 如果同時有很多人都需要牛奶,由於奶牛產量有限(假設一頭奶牛每天能產出一加侖牛奶),你只能讓他們先回家,隔天再來。
- 通過增加奶牛來擴大生產量。因為只有同村人能購買牛奶,所以產量溢位時會造成浪費。
沒有快取,你將受限於服務的計算能力。快取被用來載入靜態資源,例如:
- 圖片
- css
- 靜態 HTML 檔案
- JavaScript 檔案
預設情況下,伺服器必須為每個傳入請求返回響應。但是載入頁面的請求通常包含上述四種資源。當你載入大圖時,伺服器將不堪重負。導致使用者需要等待漫長的載入時間。
理想情況下,你希望通過儲存常見請求的響應來減輕伺服器的壓力。通過快取,伺服器不需要處理每一個新的請求就能快速響應。當然,你也可以隨時購買更多的伺服器去分解請求壓力,但這成本非常高。
什麼是服務端快取?
回到農場場景,我們怎樣才能更容易地經營好奶牛場呢?答案是擁有一家帶有冷藏技術的超市!如此一來人們就不需要親自到奶牛場去喝牛奶。你也可以將牛奶安全地存放一段時間。
超市緩解了農場壓力。因為奶牛不會實時生產,超市能夠解決實時的問題。你要做的就是保持奶牛每天的產量!更好的是,周圍村莊的居民隨時都可以在超市購買到新鮮牛奶。
就像超市一樣,伺服器端快取可以處理高併發的請求,並更快速,更可靠地提供內容。上圖中,有一個術語是快取代理——一種伺服器,用於儲存常見的請求響應。快取代理將攔截常見請求並快速傳遞響應。它可以防止這些請求對主 Web 伺服器造成壓力。
看了上文,你可能有一堆問題,比如:
- 什麼是高併發?
- 快取代理能響應多長時間?
回答上面問題可能需要很長的一篇文章,現在,你需要了解“新鮮度”的概念。快取代理在不同時間快取不同的檔案,並且需要決定是否繼續快取某些檔案。這些問題的答案取決於快取策略。
這也像超市裡的牛奶一樣,超市經理需要在牛奶保質期過後將牛奶丟棄。快取代理通過快取命中率(可通過快取伺服器提供的內容的百分比)來衡量其成功率。
什麼是 CDN?
到目前為止,你已經有了一家商店,相比以前這是很大的進步。但是如果你想把牛奶賣給更遠的人,就需要開更多的門店。
開了更多更遠的門店,你就能把牛奶分配到這些門店銷售。從而滿足更多人群的需求。這就類似於 CDN —— 位於世界各地的一系列伺服器。
作為使用者,你使用大多數網站的感覺都是非常快速的,原因之一就是使用了 CDN 來加速靜態檔案的載入。
如果你在英格蘭嘗試載入快取在弗吉尼亞州伺服器中的檔案,將有一些延遲,因為原始訊號只能沿著數千英里的電纜傳輸。本地快取代理將會使網站載入得更快。
伺服器可以將靜態資源的副本傳送到 CDN 網路中的每個代理伺服器,並且它們可以處理本地請求,直到資源過期。一些常見的 CDN 提供商包括 Rackspace , Akamai 和 Amazon Web Services 。
瀏覽器快取
有了商店,全世界的人都可以快速地購買農場牛奶。但是購買之後他們還是要快速地喝完,因為無法儲存在自己家裡。怎麼解決呢?非常簡單,在家裡放一個冰箱唄。
有了冰箱,你可以將牛奶儲存在家裡而不用送回超市。回到快取方面,指的是儲存靜態資源的本地位置——客戶端,而代理伺服器位於遠端位置。
值得注意的是,牛奶不會自動神奇地送到冰箱。需要你從超市購買回家,然後放入冰箱。所以首次請求還是必要的,之後就可以將其快取在本地。
瀏覽器怎麼知道何時從伺服器請求新資源呢?解決不了這個問題,你將無法更新本地檔案的版本。
就好比每瓶牛奶都有保質期,伺服器在 HTTP 響應頭部新增某種識別符號。實際上有4個獨立的 HTTP 快取系統。上述場景就類似“保質期”的方法,要求瀏覽器在傳送檔案之前需要檢查伺服器。
何時開始使用快取?
假設你正在開發一個 app。如果只有幾千個使用者,你不需要擔心快取問題,因為伺服器消耗比較低。然而當應用擴張時,還想繼續保持 app 速度和效率,那麼就需要實現快取。
例如,(Heroku)[zh.wikipedia.org/zh-sg/Herok…] 是部署 Web 應用程式的絕佳工具。但是,它要求使用單獨的伺服器實現快取,例如亞馬遜的 CloudFront 或 CloudFlare 。這需要更多時間來學習這些工具的使用。
在瀏覽器端,當你嘗試使用新的靜態資源重新載入頁面時,會由於資源已經快取到本地,所以頁面根本不會更改。無論重新整理頁面多少次,都沒有任何變化。
這通常是因為瀏覽器端的一些快取協議。要繞過瀏覽器的快取並從伺服器請求新資源,你可以在 Mac 上使用 Cmd + Shift + R
或在 Window 上使用 Ctrl + Shift + R
。