全棧必備 緩存cache

Cache: a collection of data duplicating original values stored elsewhere on a computer, usually for easier access—— 維基百科

緩存是系統快速響應中的一種關鍵技術,是一組被保存起來以備將來使用的東西,介於應用開發和系統開發之間,是產品經理們經常顧及不到的地方,算是技術架構中的非功能性約束吧。

也就是說,緩存是系統調優時常用且行之有效的手段,無論從操作系統還是應用系統,緩存策略無處不在。

很多技術都打着緩存的旗號,所以談起緩存往往似是而非,與語境有着緊密的關係,換個說法,來看一看緩存在不同場景的分類。

客戶端緩存

瀏覽器的緩存可以將之前渲染的頁面保存爲文件,當用戶再次訪問時可用避開網絡連接,從而減少負載。現在的HTML5支持了本地存儲,大部分BS 應用都可以舉重若輕了。

如何把客戶端緩存對於業務組件透明和客戶端緩存數據及時更新,是客戶端緩存能否成功應用的關鍵。

客戶端可以將內容緩存在內存,文件,或本地數據庫(例如Sqlite)中。

例如,iOS 的圖片緩存框架SDWeb架構如下:

SDweb

web代理

web 代理的作用跟瀏覽器的內置緩存類似,只是位於瀏覽器和互聯網之間,網絡請求通過代理來中繼。對於企業而言,即可以節省成本,又能提高性能。

對於Web代理而言,曾經流行的是Squid,它支持建立複雜緩存層級結構的能力,詳細的日誌、高性能緩存以及用戶認證支持。Squid同時支持各種插件,例如Squid Guard就是一個提供URL過濾的插件,對於屏蔽某些站點和內容十分有用。如果想分析Squid的各種指標,webalizer 應該是個不錯的選擇。

Squid 的內部機制如下:

Squid

邊緣緩存

邊緣緩存位於應用服務器的前面,可以處理來自不同用戶的請求,主要用於向用戶提供靜態的內容,以減少應用服務器的介入。邊緣緩存的商業化服務就是CDN了,例如AWS 的Cloud Front,我國的ChinaCache等。

邊緣緩存的一個有名的開源工具就是varnish,在默認情況下進行保守緩存。也就是說,varnish 只緩存它所知的安全內容。varnish的一個特性是使用虛擬內存,精妙之處在於利用了操作系統的管理機制。varnish可以高度定製如何處理請求,緩存哪些內容。

Varnish 的內部機制如下:

Varnish
詳情參見www.varnish-cache.org。

平臺緩存

平臺緩存是用來寫應用的框架,或者緩存的專用庫(如PHP中的Smarty模版庫)。

Java 語言中,緩存框架更多,例如EHcache,Cacheonix,Voldemort,JBoss Cache等等。

看一下EHcache的系統結構結構: 
EHCache 
Ehcache是一個Java實現的開源分佈式緩存框架,可以讓數據保存在不同服務器的內存中,在需要數據的時候可以快速存取。通過聲明配置、在xml中配置、在程序裏配置或者調用構造方法時傳入不同的參數。

Voldemort是一款基於Java開發的分佈式鍵-值緩存系統,像JBoss Cache一樣,Voldemort同樣支持多臺服務器之間的緩存同步,以增強系統的可靠性和讀取性能。 
Voldemort

簡單來說,就平臺級緩存而言,只需要在框架側配置一下屬性即可,而不需要調用特定的方法或函數。

應用緩存

應用級緩存,需要自己通過代碼來實現緩存。這裏是NoSQL的勝場,不論是Redis 還是MongoDB,都可以作爲應用緩存的工具。一個典型的方式是,每分鐘或一段時間後統一生成某類頁面存儲在緩存中,也可以在熱數據變化時更新緩存。

Redis 在應用級緩存中的作用舉足輕重,新浪微博有着幾乎世界上最大的redis 集羣。 Redis支持主從同步。數據可以從主服務器向任意數量的從服務器上同步,從服務器可以是關聯其他從服務器的主服務器。這使得Redis可執行單層樹複製。存盤可以有意無意的對數據進行寫操作。由於完全實現了發佈/訂閱機制,使得從數據庫在任何地方同步樹時,可訂閱一個頻道並接收主服務器完整的消息發佈記錄。同步對讀取操作的可擴展性和數據冗餘很有幫助。

Redis 的客戶端編程語言衆多,可以滿足絕大多數的應用。

Redis_client

數據庫緩存

數據庫緩存是一類特殊的緩存。大多數數據庫不需要配置就可以快速運行,但並沒有爲特定的需求進行優化。在數據庫調優的時候,緩存優化是一項很重要的工作。

MySQL爲例,MySQL中使用了查詢緩衝機制,將SELECT語句和查詢結果存放在緩衝區中,以後對於同樣的SELECT語句,將直接從緩衝區中讀取結果,以節省查詢時間,提高了SQL查詢的效率。

通過調節以下幾個參數可以知道query_cache_size設置得是否合理:

  • Qcache inserts
  • Qcache hits
  • Qcache lowmem prunes
  • Qcache free blocks
  • Qcache total blocks

當然,深入數據庫還有很多值得學習的地方。

緩存的協議支持

對web應用而言,http1.0 提供了一些很基本的緩存特性,例如在服務器側設置Expires 的http頭來告訴客戶端在重新請求文件之前緩存多久是安全的,可以通過if-modified-since 的條件請求來使用緩存。其中,發送的時間是文件最初被下載的時間,而不是即將過期的時間,如果文件沒有改變,服務器可以用304-Not Modified 來應答。客戶端收到304代碼,就可以使用緩存的文件版本了。客戶端可以設置Pragma:no-cache從服務器之間獲取內容。

Http 1.1有了較大的增強,緩存系統被形式化了,引入了實體標籤e-tags,是文件或對象的唯一標識。這意味着可以請求一個資源、提供所持有的文件,然後詢問服務器這個文件是否有變化。如果某一個文件的e-tag 是有效的,服務器會生成304-Not Modified 應答,並提供正確文件的e-tag,否則,發送200-OK應答。以瀏覽器爲例的示意圖如下: 
這裏寫圖片描述

關於HTTP2.0中有關緩存的技術,還有待研究。

總而言之,緩存——cache,是一種挺複雜的技術,除了應用場景之外,更進一步,還要理解命中,Cache Miss,存儲成本,索引成本,失效,替代策略的諸多概念,從而瞭解緩存算法,真正的掌握緩存技術。

發佈了55 篇原創文章 · 獲贊 61 · 訪問量 60萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章