緩存系列篇

分享目錄

1、  緩存概述

2、  瀏覽器緩存

3、  CDN緩存

4、  反向代理緩存

5、  本地緩存

6、分佈式緩存


四、反向代理緩存

反向代理是指在網站服務器機房部署代理服務器,實現負載均衡,數據緩存,安全控制等功能。

4.1 緩存的原理

反向代理位於應用服務器機房,處理所有對WEB服務器的請求。如果用戶請求的頁面在代理服務器上有緩衝的話,代理服務器直接將緩衝內容發送給用戶。如果沒有緩衝則先向WEB服務器發出請求,取回數據,本地緩存後再發送給用戶。通過降低向WEB服務器的請求數,從而降低了WEB服務器的負載。

反向代理一般緩存靜態資源,動態資源轉發到應用服務器處理。常用的緩存應用服務器有Varnish,Ngnix,Squid

有關nginx相關的文章將在後續發佈,望多多支持!

五、分佈式緩存

CDN,反向代理緩存,主要解決靜態文件,或用戶請求資源的緩存,數據源一般爲靜態文件或動態生成的文件(有緩存頭標識)。

分佈式緩存,主要指緩存用戶經常訪問數據的緩存,數據源爲數據庫。一般起到熱點數據訪問和減輕數據庫壓力的作用。目前分佈式緩存設計,在大型網站架構中是必備的架構要素。常用的中間件有Memcache,Redis。

5.1 Memcached

Memcache特性:

(1)使用物理內存作爲緩存區,可獨立運行在服務器上。每個進程最大2G,如果想緩存更多的數據,可以開闢更多的memcache進程(不同端口)或者使用分佈式memcache進行緩存,將數據緩存到不同的物理機或者虛擬機上。

(2)使用key-value的方式來存儲數據,這是一種單索引的結構化數據組織形式,可使數據項查詢時間複雜度爲O(1)。

(3)協議簡單:基於文本行的協議,直接通過telnet在memcached服務器上可進行存取數據操作,簡單,方便多種緩存參考此協議;

(4)基於libevent高性能通信:Libevent是一套利用C開發的程序庫,它將BSD系統的kqueue,Linux系統的epoll等事件處理功能封裝成一個接口,與傳統的select相比,提高了性能。

(5)內置的內存管理方式:所有數據都保存在內存中,存取數據比硬盤快,當內存滿後,通過LRU算法自動刪除不使用的緩存,但沒有考慮數據的容災問題,重啓服務,所有數據會丟失。memcached默認情況下采用了名爲Slab Allocator的機制分配、管理內存。在該機制出現以前,內存的分配是通過對所有記錄簡單地進行malloc和free來進行的。但是,這種方式會導致內存碎片,加重操作系統內存管理器的負擔,最壞的情況下,會導致操作系統比memcached進程本身還慢。Slab Allocator就是爲解決該問題而誕生的。

Slab Allocation的原理相當簡單。 將分配的內存分割成各種尺寸的塊(chunk),並把尺寸相同的塊分成組(chunk的集合)


Slab Allocator的缺點

Slab Allocator解決了當初的內存碎片問題,但新的機制也給memcached帶來了新的問題。這個問題就是,由於分配的是特定長度的內存,因此無法有效利用分配的內存。

(6)分佈式:各個memcached服務器之間互不通信,各自獨立存取數據,不共享任何信息。服務器並不具有分佈式功能,分佈式部署取決於memcache客戶端。

如下圖所示:


(7)緩存策略:Memcached的緩存策略是LRU(最近最少使用)到期失效策略。在memcached內存儲數據項時,可以指定它在緩存的失效時間,默認爲永久。當memcached服務器用完分配的內時,失效的數據被首先替換,然後也是最近未使用的數據。在LRU中,memcached使用的是一種Lazy Expiration策略,自己不會監控存入的key/vlue對是否過期,而是在獲取key值時查看記錄的時間戳,檢查key/value對空間是否過期,這樣可減輕服務器的負載

5.1.1 Memcached的工作原理

MemCache的工作流程如下:

(1)先檢查客戶端的請求數據是否在memcached中,如有,直接把請求數據返回,不再對數據庫進行任何操作;

(2)如果請求的數據不在memcached中,就去查數據庫,把從數據庫中獲取的數據返回給客戶端,同時把數據緩存一份到memcached中(memcached客戶端不負責,需要程序實現);

(3)每次更新數據庫的同時更新memcached中的數據,保證一致性;

(4)當分配給memcached內存空間用完之後,會使用LRU(Least Recently Used,最近最少使用)策略加上到期失效策略,失效數據首先被替換,然後再替換掉最近未使用的數據。

5.1.2 Memcached集羣

memcached 雖然稱爲 “ 分佈式 ” 緩存服務器,但服務器端並沒有 “ 分佈式 ” 功能。每個服務器都是完全獨立和隔離的服務。memcached 的分佈式,是由客戶端程序實現的。當向memcached集羣存入/取出key value時,memcached客戶端程序根據一定的算法計算存入哪臺服務器,然後再把key value值存到此服務器中。

分佈式算法:選擇服務器算法有兩種,一種是根據餘數來計算分佈,另一種是根據散列算法來計算分佈。

餘數算法:先求得鍵的整數散列值,再除以服務器臺數,根據餘數確定存取服務器。

優點:計算簡單,高效;

缺點:在memcached服務器增加或減少時,幾乎所有的緩存都會失效。

一致性hash算法

按照常用的hash算法來將對應的key哈希到一個具有2^32次方個桶的空間中,即0~(2^32)-1的數字空間中。現在我們可以將這些數字頭尾相連,想象成一個閉合的環形。如下圖


現在我們將object1、object2、object3、object4四個對象通過特定的Hash函數計算出對應的key值,然後散列到Hash環上。如下圖:

 Hash(object1) = key1;

 Hash(object2) = key2;

Hash(object3) = key3;

 Hash(object4) = key4;


在採用一致性哈希算法的分佈式集羣中將新的機器加入,其原理是通過使用與對象存儲一樣的Hash算法將機器也映射到環中(一般情況下對機器的hash計算是採用機器的IP或者機器唯一的別名作爲輸入值),然後以順時針的方向計算,將所有對象存儲到離自己最近的機器中。

假設現在有NODE1,NODE2,NODE3三臺機器,通過Hash算法得到對應的KEY值,映射到環中,其示意圖如下:

Hash(NODE1) = KEY1;

Hash(NODE2) = KEY2;

Hash(NODE3) = KEY3;


通過上圖可以看出對象與機器處於同一哈希空間中,這樣按順時針轉動object1存儲到了NODE1中,object3存儲到了NODE2中,object2、object4存儲到了NODE3中。在這樣的部署環境中,hash環是不會變更的,因此,通過算出對象的hash值就能快速的定位到對應的機器中,這樣就能找到對象真正的存儲位置了。

1. 節點(機器)的刪除

以上面的分佈爲例,如果NODE2出現故障被刪除了,那麼按照順時針遷移的方法,object3將會被遷移到NODE3中,這樣僅僅是object3的映射位置發生了變化,其它的對象沒有任何的改動。如下圖:


2. 節點(機器)的添加 

如果往集羣中添加一個新的節點NODE4,通過對應的哈希算法得到KEY4,並映射到環中,如下圖:


通過按順時針遷移的規則,那麼object2被遷移到了NODE4中,其它對象還保持這原有的存儲位置。通過對節點的添加和刪除的分析,一致性哈希算法在保持了單調性的同時,還是數據的遷移達到了最小,這樣的算法對分佈式集羣來說是非常合適的,避免了大量數據遷移,減小了服務器的的壓力。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章