快取(Cache)也是經常會被問到的經典題目。
Cache 是什麼?
在硬體或是軟體開發中,經常會碰到一個名詞——「快取(cache)」。
根據 AWS 的定義,快取指的是一個具有高速特性的資料儲存層,特別用來存部分的資料,而這些被存起來的資料通常都是暫時性的(或者設定時效),之後如果再次遇到針對這些資料的讀取時,讓我們能夠直接從快取取出結果,以加速系統的回應速度。
In computing, a cache is a high-speed data storage layer which stores a subset of data, typically transient in nature, so that future requests for that data are served up faster than is possible by accessing the data’s primary storage location. Caching allows you to efficiently reuse previously retrieved or computed data.
實務上,除了將資料儲存在快取加速回應/計算速度之外,也常常將計算成本昂貴的資料也放進快取,從而降低計算成本以及對系統的負荷。
有效的快取通常會降低系統延遲(latency)或是增加系統的吞吐量(throughput),如果加了快取卻不見上述 2 個指標有明顯的改善,就代表快取並沒有正常發揮,此時就得進一步深入分析其原因。
各式快取的應用場景
上圖是經典現代的 HTTP 應用分層(application layer)圖,闡述使用者透過 mobile APP 或者瀏覽器(browser)發出請求(request),這些請求會經過網際網路(Internet)取得所要求的內容(content),或者更進一步透過與應用(application)互動取得資料,這些請求甚至可能需要使用資料庫才能完成。
這其中每個環節都有相關的快取技術能夠使用。
客戶端 Client-Side
如要在客戶端加上快取機制,需要視客戶(client)使用的平台選擇不同的快取機制,例如 Android 提供 HttpResponseCache, iOS 提供 URLCache, 而瀏覽器則有 Cache-Control 與 localStorage 可以做快取。
不過現今使用者至少能透過 Web, Android APP, iOS APP 3 種平台與應用互動,如果選擇在客戶端實作快取,那麼勢必得針對 3 種實作 3 種快取,開發與維護成本相對將快取加在系統後端(backend)高很多,所以一般快取並不會優先選擇加在客戶端。
DNS 快取
現今很多應用都是架構在 HTTP 協定之上,所以 DNS(Domain Name System)也在 HTTP 通訊中扮演著相當重要的角色,DNS 負責將網域(domain)轉換成 IP 位址,讓電腦能夠連到正確的伺服器。
DNS 伺服器在查詢 IP 位址時,也多少會花費一些時間,所以只要將 DNS 查詢結果快取起來,當下次需要再次解析相同的網域時,就能夠直接從快取中取得解析結果,不需再次詢問 DNS 伺服器。
目前多數主流作業系統都有實作 DNS Cache, 甚至瀏覽器也都有這樣的機制,所以並不需要操心。
Web Content
這一層的快取主要是為了能夠快速取得 Web Content, 例如取得圖片、檔案等等,所以除了前述的 Cache-Control 之外,還可以選擇使用常見的:
- CDN(Content Delivery Network) 將圖片或檔案存在離使用者地理位置較近的伺服器上,減少使用者傳輸圖片、檔案等所需的時間
- Reverse Proxy 反向代理伺服器,詳見 Wikipedia
Application
在應用端實作快取是最一魚多吃也最彈性的解決方案,不僅所有平台都能夠統一享受到快取之外,後端也能夠更彈性地自由更新快取資料,所以一般都會先在 Application 的 API 先實作快取。
一般有下列這些選擇可供使用:
- Key/Value data stores, 例如 memcached 或 Redis
- Local cache, 例如 cache 在 Process 的記憶體之中,不過問題相對較多(例如,在多 Processes 情況下容易造成 Cache 重複資料,導致浪費記憶體的情況,或者資料不一致的問題,甚至因為資料都快取在 Process 記憶體中,所以更新也不方便)
Database
資料庫通常是應用(application)中不可或缺的一環,而有些資料庫天生就無法應付大量的請求(requests), 因此在大流量的系統中,通常也都會利用快取減少需要進到資料庫的請求,例如將資料庫查詢結果快取到 Key/Value data stores, 進行資料庫查詢前,先至 Key/Value data stores 查詢是否有快取存在,或者利用資料庫本身就提供的快取功能降低查詢資料庫的負荷,例如 Elasticsearch 對於搜尋也有提供 query cache 的功能。
以上,就是關於快取的概念。
References
https://aws.amazon.com/caching/?nc1=h_ls
https://en.wikipedia.org/wiki/Reverse_proxy
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control