Memcached分佈式緩存快速入門

1、從單機到分佈式php

走向分佈式第一步就是解決:多臺機器共享登陸信息的問題。
•例如:如今有三臺機器組成了一個Web的應用集羣,其中一臺機器用戶登陸,而後其餘另外兩臺機器共享登陸狀態?
•解決1:AspNet 進程外的Session。
•解決2:用數據庫存儲當前登陸狀態。
•解決3:Memcache (性能最好,相似的:Redis,NoSql)

 

2、爲何要使用Memcached?html

•高併發訪問數據庫的痛楚:死鎖!
•磁盤IO之痛:
•多客戶端共享緩存
•Net + Memory  >> IO   
•讀寫性能完美  1s:讀取能夠1w次。 寫:10w
•超簡單集羣搭建 Cluster
•開源 Open Source
•沒有提供主從賦值功能,也沒提供容災等功能,單純解決性能問題。(Redis有容災功能,將內存數據備份到磁盤上)
•學習成本很是低,入門很是容易
•豐富的成功的案例
 
3、Memcached基礎原理:
•位置:放在服務器端,經過Socket方式進行通訊。
•數據:鍵值對存儲
•內存處理的算法:
•本質就是一個大的哈希表。key最大長度是255個字符。
•內存模型:Memcache預先將可支配的內存空間進行分區(Slab),每一個分區裏再分紅多個塊(Chunk)大小1MB,但同一個分區裏:塊的長度(bytes)是固定的。
•插入數據:查找適合本身長度的塊,而後插入,會有內存浪費。
•插入數據規則:閒置 > 過時 > 最少訪問     
•惰性刪除:它並無提供監控數據過時的機制,而是惰性的,當查詢到某個key數據時,若是過時那麼直接拋棄。
•集羣搭建原理:Memcache服務器端並無提供集羣功能,可是經過客戶端的驅動程序實現了集羣配置。
•客戶端實現集羣的原理:首先客戶端配置多臺集羣機器的ip和端口的列表。而後客戶端驅動程序在寫入以前,首先對key作哈希處理獲得哈希值後對總的機器的個數進行取餘而後就選擇餘數對應的機器。

其餘說明:
key最大255個字符,item內存塊最大1MB,固然key/item最好都別太大,最長過時時間是30天 

Memcache預先將可支配的內存空間進行分區(Slab),每一個分區裏再分紅多個塊(Chunk),但同一個分區裏:塊的長度(bytes)是固定的。
將記錄從Memcache刪除後,已經分配的內存(即Chunk),也不會被釋放,而是會重複利用,這樣就完全解決了內存碎片的問題
Memcache採用「惰性」方式來應對記錄的超期問題


一致性哈希處理: http://www.cnblogs.com/lanceyan/archive/2013/05/13/3075044.html

解決多線程問題:
3. CAS的基本原理
Memcached於1.2.4版本新增CAS協議,類同於Java併發包中CAS(Compare and Set)原子操做,用來處理同一item被多個線程更改過程的併發問題.
基本原理很是簡單,簡而言之就是」版本號」.每一個存儲的數據對象都有一個版本號.在Memcached中,每一個key關聯有一個64bit長度的long型惟一數值,表示該key對應value的版本號.
這個數值由Memcached產生,從1開始,且同一Memcached不會重複,在兩種狀況下這個版本數值會加,即新增與更新,而刪除item版本值不會減少.

咱們能夠從下面的例子來理解:
若是不採用CAS,則有以下的情景:
第一步,A取出數據對象X;
第二步,B取出數據對象X;
第三步,B修改數據對象X,並將其放入緩存;
第四步,A修改數據對象X,並將其放入緩存。
咱們能夠發現,第四步中會產生數據寫入衝突。

若是採用CAS協議,則是以下的情景。
第一步,A取出數據對象X,並獲取到CAS-ID1;
第二步,B取出數據對象X,並獲取到CAS-ID2;
第三步,B修改數據對象X,在寫入緩存前,檢查CAS-ID與緩存空間中該數據的CAS-ID是否一致。結果是「一致」,就將修改後的帶有CAS-ID2的X寫入到緩存。
第四步,A修改數據對象Y,在寫入緩存前,檢查CAS-ID與緩存空間中該數據的CAS-ID是否一致。結果是「不一致」,則拒絕寫入,返回存儲失敗。
View Code

 

使用場景:算法

緩存放頻繁訪問但不多變化的內容:
如:類別、禁用詞(用正則匹配)、數據庫

string str = string.Join(list.ToArray()); //aa|bb|cc
Regex.IsMatch(msg,str);

 

4、Windows下使用Memcachewindows

•下載Memcache服務程序: 點擊下載>>
•將服務程序拷貝到一個磁盤上的目錄,如D:\Memcached
•安裝服務:
cmd→ D: 回車 定位到D盤
cd D:\Memcached 回車 定位到D盤下Memcached目錄
memcached.exe -d install 安裝memcached服務
memcached.exe -d start   啓動memcached服務  (打開服務監控窗口能夠查看服務是否啓動。restart重啓,stop關閉服務)
 
•檢查服務是否安裝成功:
1.先確認已安裝telnet客戶端,未安裝的先安裝。 安裝教程>>
鏈接到Memcache控制檯:telnet 服務器IP地址 11211  如:telnet 127.0.0.1 11211 (用本地測試的,若是是其餘服務器則改成服務器地址。端口號11211爲固定的。)
輸入cmd命令檢查:stats 檢查當前服務狀態。
出現上面信息則表示安裝成功。
 
•卸載服務:Memcached.exe -d uninstall(先關閉服務)
•遇到問題:win8下安裝服務。沒法啓動此程序,由於計算機中丟失 MSVCR71.dll。嘗試從新安裝該程序以解決此問題。下載dll地址:http://www.dll-files.com/dllindex/dll-files.shtml?msvcr71
 

其餘說明:緩存

將Memcache.exe安裝爲Windows服務:Memcache.exe -d install
啓動Memcache服務:Memcache.exe -d start
啓動Memcache服務(windows命令):net start "Memcache Server"
中止Memcache服務(windows命令):net stop "Memcache Server"
鏈接到Memcache控制檯:telnet ServerIP 11211
打印當前Memcache服務器狀態:stats
打印當前Memcache服務器Items(記錄)的統計信息:stats items
打印當前Memcache服務器Slab(分區)及Chunk(塊)的統計信息:stats slabs
打印指定Slab中的KEY列表(可用於遍歷items,但效率較低,慎用!):stats cachedump SlabId Limit_num。顯示結果:ITEM KeyName [ValueByteLength b; LastAccessTime s]。值得注意的是,通過測試確認:那個LastAccessTime並非記錄到期時間,而是最後一次的get時間,而且get以後,也不會自動延長expiry(到期時間)。
添加新記錄:add KeyName 0 0 ValueByteLength [回車] ValueContent
刪除記錄 : delete KeyName
添加或更新記錄 : set KeyName 0 0 ValueByteLength [回車] ValueContent
更新記錄 : replace KeyName 0 0 ValueByteLength [回車] ValueContent
取值:get key
參考:http://www.cnblogs.com/lost-1987/articles/3069460.html

http://wenku.baidu.com/view/e30db586ec3a87c24028c401.html

也能夠圖形化監控 Memcached 的運行狀態
http://livebookmark.net/journal/2008/05/21/memcachephp-stats-like-apcphp/

在 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\memcached Server 下面找到一個 ImagePath 的字符串項,正好是服務的執行路徑的字符串,雙擊該串,在後面加入 -l 192.168.1.135 -m 45 -p 12345 (訪問ip爲:192.168.1.135 使用45M內存,12345爲端口),再啓動服務。
View Code

 

5、應用服務器

1.下載.NET版memcached客戶端API組件 放到自建的Lib文件夾session

2.添加這些dll引用(Commons.dll,ICSharpCode.SharpZipLib.dll,log4net.dll)多線程

3.封裝MemcacheHelper代碼以下:併發

public class MemcacheHelper
    {
        private static readonly MemcachedClient mc = new MemcachedClient();
static MemcacheHelper() //靜態構造函數只會執行一次  { string[] serverlist = { "127.0.0.1:11211","10.0.0.132:11211" };//Memcache服務器IP地址和端口號,這裏用本地機子進行測試。(可存放多個服務器信息,無效的服務器會自動被忽略。具體往哪臺服務器存,會根據內部哈希算法自動去選擇,不用咱們去考慮。) //初始化池 SockIOPool pool = SockIOPool.GetInstance(); pool.SetServers(serverlist); pool.InitConnections = 3; pool.MinConnections = 3; pool.MaxConnections = 5; pool.SocketConnectTimeout = 1000; pool.SocketTimeout = 3000; pool.MaintenanceSleep = 30; pool.Failover = true; pool.Nagle = false; pool.Initialize(); //得到客戶端實例(能夠認爲是telnet或socket客戶端) MemcachedClient mc = new MemcachedClient(); mc.EnableCompression = false; } /// <summary> /// 向Memcache存儲數據 /// </summary> /// <param name="key"></param> /// <param name="value"></param> public static void Set(string key, object value) { mc.Set(key, value); } public static void Set(string key, object value, DateTime time) { mc.Set(key, value, time);//絕對過時時間  } /// <summary> /// 獲取Memcache中的數據 /// </summary> /// <param name="key"></param> /// <returns></returns> public static object Get(string key) { return mc.Get(key); } /// <summary> /// 刪除 /// </summary> /// <param name="key"></param> /// <returns></returns> public static bool Delete(string key) { if (mc.KeyExists(key)) { return mc.Delete(key); } return false; } }

調用:

MemcacheHelper.Set("test","myValue");

若是存儲複雜類型數據則須要進行序列號處理:

MemcacheHelper.Set(sessionId,SerializerHelper.SerializerToString(userInfo));

序列化處理:(添加dll引用:Newtonsoft.Json) 點擊下載FrameWork4.5版本>>

using Newtonsoft.Json; using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CZBK.HeiMaOA.Common
{
    public class SerializerHelper
    {
        public static string SerializerToString(object obj)
        {
            return JsonConvert.SerializeObject(obj);
        }
    }
}

 

 

6、源碼下載:

點擊下載>>

點擊下載數據庫文件>>

測試:

相關文章
相關標籤/搜索