全棧必備——快取Cache

abel_cao發表於2016-11-06

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 語言中,快取框架更多,例如EhcacheCacheonixVoldemortJBoss 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,儲存成本,索引成本,失效,替代策略的諸多概念,從而瞭解快取演算法,真正的掌握快取技術。

相關文章