Memcache內存緩存框架

 

轉載請註明原文地址:http://www.javashuo.com/article/p-zqgsncbe-eq.htmlhtml

 

一:Memcache是什麼,爲何要用它

  MemCache是一個高性能、「分佈式」的內存緩存系統,它經過在內存中緩存數據和對象來減小讀取數據庫的次數,從而提升了網站訪問的速度,減輕數據庫的負載。linux

  MemCaChe是一個存儲鍵值對的HashMap,在內存中對任意的數據(好比字符串、對象等)使用key-value形式進行存儲。redis

  數據能夠來自數據庫查詢、API調用結果返回,或者網頁傳輸過來的數據(session信息、request信息或者所攜帶的參數)。算法

   

二:Memcache安裝與運維

  一、在本機或者集羣服務器上安裝Memcache數據庫

(Ubuntu/Debian)
sudo apt-get install libevent ibevent-dev
sudo apt-get install memcached


(Redhat/Fedora/Centos)
yum install libevent libevent-devel
yum install memcached

 

  二、啓動memcache:使用 memcached命令api

  cd到memcached目錄/bin下,經過 memcached [-options][value] 來啓動memcache。緩存

  啓動選項:安全

  • -d是啓動一個守護進程;
  • -m是分配給Memcache使用的內存數量,單位是MB;
  • -u是運行Memcache的用戶;
  • -l是監聽的服務器IP地址,能夠有多個地址;
  • -p是設置Memcache監聽的端口,,最好是1024以上的端口;
  • -c是最大運行的併發鏈接數,默認是1024;
  • -P是設置保存Memcache的pid文件。

 

  三、memcache服務器運維服務器

  咱們還能夠在終端窗口使用telnet指令,經過IP和端口鏈接到memcache服務器進行操做。session

telnet HOST PORT

  

  四、memcache操做指令

  1)存儲指令

  

 

  2)查找與操做指令

  

 

  3)運維指令

  

 

三:Memcache在開發中的應用——Java

  一、添加依賴

  二、鏈接memcache服務器

// 鏈接 Memcached 服務,建立memcache客戶端對象
MemcachedClient mcc = new MemcachedClient(new InetSocketAddress("ip", port));

  三、經過memcache對象調用api進行存儲、查找操做,api的參數同上面第二點中的指令參數

 // 存儲數據
Future fo = mcc.set(key, 有效期, 值);
//查找數據
mcc.get(key)

  四、操做完成後關閉鏈接,以避免佔用memcache服務器資源

// 關閉鏈接
mcc.shutdown();    

 

四:Memcache深刻解讀

  一、memcache與redis的區別和聯繫

  1)存儲數據類型區別

  redis:支持較多的數據類型(String/list/set/sortset/hash)做爲值;每一個value最大數據存儲量爲1G;支持持久化;目前只支持在linux下運行。

  memcache:各類框架(tp/yii等等)都支持使用;session的信息能夠很是方便的保存到memcache中,每一個key保存的數據量最大爲1M;不支持持久化,斷電重啓就沒有了。

  2)分佈式模式區別

  redis:主從模式,一個redis負責數據寫入,其餘多個redis負責數據讀取。

  memcache:平均分攤模式,每一個子服務器之間都是平級的,每一個服務器都要執行數據的寫入、讀取操做。

  3)聯繫

  二者都是把數據保存在內存中,優化數據存取速度。

 

  二、memcache的數據類型存儲

  1)基本數據類型——轉化爲String字符串格式來存儲

  2)引用類型對象——原型存儲

  因爲原型存儲對資源的消耗比較大,爲了節省資源,能夠把引用類型信息都變爲字符串形式進行存儲,這時須要進行 序列化 操做。

 

  三、memcache的分佈式

  memcache的分佈式 不是經過架構手段去實現的,咱們只須要部署多臺memcache服務器,而後在代碼中爲memcache對象添加多個server便可。

  其分佈式特性是內置好了的,無需咱們再經過架構手段實現一遍。

  memcache自己有算法,能夠保證數據「平均」地存儲在不一樣的服務器裏邊。【注意:是平均,而不是複製,各臺memcache中存儲的內容是不一樣的。】

 

 

  四、Memcache的訪問模型(參考:http://www.javashuo.com/article/p-ngxgekwb-cr.html)

  

  MemCache雖然被稱爲"分佈式緩存",可是MemCache自己徹底不具有分佈式的功能,MemCache集羣之間不會相互通訊(與之造成對比的,好比JBoss Cache,某臺服務器有緩存數據更新時,會通知集羣中其餘機器更新緩存或清除緩存數據),所謂的"分佈式",徹底依賴於客戶端程序的實現[經過代碼]。

  MemCache一次寫緩存的流程:

  1)應用程序輸入須要寫緩存的數據

  2)API將Key輸入路由算法模塊,路由算法根據Key和MemCache集羣服務器列表獲得一臺服務器編號

  3)由服務器編號獲得MemCache及其的ip地址和端口號

  4)API調用通訊模塊和指定編號的服務器通訊,將數據寫入該服務器,完成一次分佈式緩存的寫操做

  讀緩存和寫緩存同樣,只要使用相同的路由算法和服務器列表,只要應用程序查詢的是相同的Key,MemCache客戶端老是訪問相同的客戶端去讀取數據,只要服務器中還緩存着該數據,就能保證緩存命中。

 

  五、memcache路由算法(參考:http://www.javashuo.com/article/p-ngxgekwb-cr.html)

  1)餘數Hash策略

  例如,key的HashCode爲50,memcache服務器有3臺,則key.hashcode % 3 == 2,路由算法將key路由到第二臺服務器上進行存儲。

  原理:因爲hashcode的隨機性,能夠保證數據「較爲平均」地分佈在memcache服務器集羣中。

  缺點:服務器集羣伸縮性差。當memcache服務器集羣橫向擴展時,服務器數量變化,會致使一樣的key路由到新的服務器上,而舊路由器上的值不會被清除。

  解決方案:

  (1)在網站訪問量低谷時段,一般是深夜,技術團隊加班,擴容、重啓服務器;

  (2)而後經過模擬請求的方式,對緩存內容從新讀寫一遍,逐漸預熱緩存,使緩存服務器中的數據從新分佈;

 

  2)一致性Hash算法

  一致性Hash算法經過一個叫作一致性Hash環的數據結構實現Key到緩存服務器的Hash映射。

  咱們將服務器節點分佈在Hash環上,每一個key路由時,指向該key沿着hash環順時針最近的服務器節點上。

  例如:服務器擴展前的Hash環

 

  當咱們新增了一臺服務器時,環上新增了一個節點:

  這樣會致使上圖中加粗部分緩存內容被從新分佈,但相比第一種策略,這樣已經優化了好多倍了。而且,集羣中緩存服務器節點越多,增長節點帶來的影響越小。

 

  六、memcache的存儲原理(參考:http://www.javashuo.com/article/p-ngxgekwb-cr.html)

  MemCache採用的內存分配方式是 固定空間分配:

  

  

  1)MemCache將內存空間分爲一組slab

  2)每一個slab下又有若干個page,每一個page默認是1M,若是一個slab佔用100M內存的話,那麼這個slab下應該有100個page

  3)每一個page裏面包含一組chunk,chunk是真正存放數據的地方,同一個slab裏面的chunk的大小是固定的

  4)有相同大小chunk的slab被組織在一塊兒,稱爲slab_class

 

  若是slab中沒有chunk能夠分配了怎麼辦:若是MemCache啓動沒有追加-M(禁止LRU,這種狀況下內存不夠會報Out Of Memory錯誤),那麼MemCache會把這個slab中最近最少使用的chunk中的數據清理掉,而後放上最新的數據。

  爲何MemCache存放的value大小是限制的:由於一個新數據過來,slab會先以page爲單位申請一塊內存,申請的內存最多就只有1M,因此value大小天然不能大於1M了。

 

  七、memcache的特性與限制

  1)MemCache中能夠保存的item數據量是沒有限制的,只要內存足夠

  2)MemCache單進程在32位機中最大使用內存爲2G,64位機則沒有限制

  3)Key最大爲250個字節,超過該長度沒法存儲

  4)單個item最大數據是1MB,超過1MB的數據不予存儲

  5)MemCache服務端是不安全的,好比已知某個MemCache節點的ip和port,能夠直接telnet過去,並經過flush_all讓已經存在的鍵值對當即失效

  6)不可以遍歷MemCache中全部的item,由於這個操做的速度相對緩慢且會阻塞其餘的操做

  7)MemCache的高性能源自於兩階段哈希結構:第一階段在客戶端,經過Hash算法根據Key值算出一個節點;第二階段在服務端,經過一個內部的Hash算法,查找真正的item並返回給客戶端。

  8)MemCache設置添加某一個Key值的時候,傳入expiry爲0表示這個Key值永久有效,然而這個Key值也會在30天以後失效,這是在源碼中寫死了的。

 

五:常見的memcache使用

  一、session共享

  一個大型網站或系統,每每部署在多臺服務器上。多臺服務器彼此之間須要共享session信息,這時能夠把session緩存在memcache中,而各服務器均可以從memcache中提取session進行分佈式處理的同時又能保持一致性。

  二、網頁內容緩存

  網站有一個頁面須要得到許多數據信息,而且這些數據信息在短期內不會發生變化時。能夠把這些數據得到出來存入到memacache中過去,供後續訪問。

相關文章
相關標籤/搜索