天天看點

開源架構 - 分布式緩存系統Memcached

Memcached簡介

百度百科

memcached是一套分布式的高速緩存系統,由LiveJournal的Brad Fitzpatrick開發,但被許多網站使用。這是一套開放源代碼軟體,以BSD license授權釋出。

memcached缺乏認證以及安全管制,這代表應該将memcached伺服器放置在防火牆後。

memcached的API使用三十二比特的循環備援校驗(CRC-32)計算鍵值後,将資料分散在不同的機器上。當表格滿了以後,接下來新增的資料會以LRU機制替換掉。由于memcached通常隻是當作緩存系統使用,是以使用memcached的應用程式在寫回較慢的系統時(像是後端的資料庫)需要額外的代碼更新memcached内的資料。

為什麼選擇Memcached

  • 高并發通路資料庫的痛點:死鎖
  • 磁盤IO之痛
  • 多用戶端共享緩存
  • Net+Memory>>IO
  • 讀寫性能完美 1s:讀取可以1w次
  • 簡單叢集搭建Cluster
  • 開源
  • 沒有提供主從指派功能,也沒有提供容災等功能,是以所有的代碼都隻是考慮性能最佳(Redis)
  • 學習成本非常低,入門非常容易
  • 豐富的成功案例 

Memcached基本原理

Socket 伺服器端

資料:鍵值對存儲

記憶體處理的算法

  • 本質就是一個大的哈希表。key最大長度是255個字元。
  • 記憶體模型:Memcache預先将可支配的記憶體空間進行分區(Slab),每個分區裡再分成多個塊(Chunk)大小1MB,但同一個分區裡:塊的長度(bytes)是固定的。
  • 插入資料:查找适合自己長度的塊,然後插入,會有記憶體浪費。
  • LRU,閑置>過期  >最少通路 
  • 惰性删除:它并沒有提供監控資料過期的機制,而是惰性的,當查詢到某個key資料時,如果過期那麼直接抛棄。

叢集搭建原理

  • Memcache伺服器端并沒有提供叢集功能,但是通過用戶端的驅動程式實作了叢集配置。

用戶端實作叢集的原理

  • 首先用戶端配置多台叢集機器的ip和端口的清單。然後用戶端驅動程式在寫入之前,首先對key做哈希處理得到哈希值後對總的機器的個數進行取餘然後就選擇餘數對應的機器。

Windows下使用Memcached

  • 下載下傳Memcached:http://www.memcached.org.cn/
  • 将服務程式拷貝到一個磁盤上的目錄
  • 安裝服務:cmd→Memcached.exe -d install 打開服務監控視窗可以檢視服務是否啟動。
  • 啟動服務:cmd→Memcached.exe -d start(restart重新開機,stop關閉服務)
  • 檢查服務是否啟動:連接配接到Memcache控制台:telnet ServerIP 11211  輸入指令:stats檢查目前服務狀态。
  • 解除安裝服務:Memcached.exe -d uninstall(先關閉服務)

Stats統計項

開源架構 - 分布式緩存系統Memcached

實戰測試

1、下載下傳安裝Memcached服務端

下載下傳完成後解壓到桌面,如下截圖

開源架構 - 分布式緩存系統Memcached

 兩種安裝方式,a:輕按兩下memcached.exe安裝。b:安裝到Windows服務中。這裡,我們推薦使用第二種安裝方式。

開源架構 - 分布式緩存系統Memcached

确認下服務是否安裝并啟動

開源架構 - 分布式緩存系統Memcached

telnet連結到Memcached服務,并檢視其stats統計項

  • 以管理者身份啟動指令控制行
  • 輸入 telnet 127.0.0.1 11211     (注意:這裡寫實際Memcached服務端IP位址,我這裡是本機127.0.0.1)
  • 輸入stats并回車
開源架構 - 分布式緩存系統Memcached

2、測試Mamcached的讀寫操作(set和get方法)

建立一個控制台應用程式,添加應用,并編寫如下代碼

開源架構 - 分布式緩存系統Memcached
開源架構 - 分布式緩存系統Memcached
開源架構 - 分布式緩存系統Memcached
1 /// <summary>      2         /// 測試MemCahed      3         /// </summary>      4         /// <param name="args"></param>      5         static void Main(string[] args)      6         {      7             string[] serverlist = { "127.0.0.1:11211", "10.0.0.132:11211" };      8       9             //初始化池     10             SockIOPool pool = SockIOPool.GetInstance();     11             pool.SetServers(serverlist);     12      13             pool.InitConnections = 3;     14             pool.MinConnections = 3;     15             pool.MaxConnections = 5;     16      17             pool.SocketConnectTimeout = 1000;     18             pool.SocketTimeout = 3000;     19      20             pool.MaintenanceSleep = 30;     21             pool.Failover = true;     22      23             pool.Nagle = false;     24             pool.Initialize();     25      26             // 獲得用戶端執行個體     27             MemcachedClient mc = new MemcachedClient();     28             mc.EnableCompression = false;     29      30             Console.WriteLine("------------測  試-----------");     31             mc.Set("test", "my value");  //存儲資料到緩存伺服器,這裡将字元串"my value"緩存,key 是"test"     32      33             if (mc.KeyExists("test"))   //測試緩存存在key為test的項目     34             {     35                 Console.WriteLine("test is Exists");     36                 Console.WriteLine(mc.Get("test").ToString());  //在緩存中擷取key為test的項目     37             }     38             else     39             {     40                 Console.WriteLine("test not Exists");     41             }     42      43             Console.ReadLine();     44      45             mc.Delete("test");  //移除緩存中key為test的項目     46      47             if (mc.KeyExists("test"))     48             {     49                 Console.WriteLine("test is Exists");     50                 Console.WriteLine(mc.Get("test").ToString());     51             }     52             else     53             {     54                 Console.WriteLine("test not Exists");     55             }     56             Console.ReadLine();     57      58             SockIOPool.GetInstance().Shutdown();  //關閉池, 關閉sockets     59      60         }     61      

View Code

啟動調試,顯示結果如下。

開源架構 - 分布式緩存系統Memcached

3、封裝MemcachedHelper類

開源架構 - 分布式緩存系統Memcached
開源架構 - 分布式緩存系統Memcached
1  public class MemcachedHelper      2     {      3         private static readonly MemcachedClient mc = null;      4       5         /// <summary>      6         /// 構造函數,預設連接配接127.0.0.1:11211      7         /// </summary>      8         static MemcacheHelper()      9         {     10             //最好放在配置檔案中     11             string[] serverlist = { "127.0.0.1:11211", "10.0.0.132:11211" };     12      13             //初始化池     14             SockIOPool pool = SockIOPool.GetInstance();     15             pool.SetServers(serverlist);     16      17             pool.InitConnections = 3;     18             pool.MinConnections = 3;     19             pool.MaxConnections = 5;     20      21             pool.SocketConnectTimeout = 1000;     22             pool.SocketTimeout = 3000;     23      24             pool.MaintenanceSleep = 30;     25             pool.Failover = true;     26      27             pool.Nagle = false;     28             pool.Initialize();     29      30             // 獲得用戶端執行個體     31             mc = new MemcachedClient();     32             mc.EnableCompression = false;     33         }     34              35         /// <summary>     36         /// 存儲資料     37         /// </summary>     38         /// <param name="key">鍵</param>     39         /// <param name="value">值</param>     40         /// <returns></returns>     41         public static bool Set(string key, object value)     42         {     43             return mc.Set(key, value);     44         }     45      46         /// <summary>     47         /// 存儲資料并指定過期時間     48         /// </summary>     49         /// <param name="key">鍵</param>     50         /// <param name="value">值</param>     51         /// <param name="time">過期時間,注意預設最大30天</param>     52         /// <returns></returns>     53         public static bool Set(string key, object value, DateTime time)     54         {     55             return mc.Set(key, value, time);     56         }     57      58         /// <summary>     59         /// 根據鍵擷取資料     60         /// </summary>     61         /// <param name="key">鍵</param>     62         /// <returns></returns>     63         public static object Get(string key)     64         {     65             return mc.Get(key);     66         }     67      68         /// <summary>     69         /// 根據鍵删除資料     70         /// </summary>     71         /// <param name="key">鍵</param>     72         /// <returns></returns>     73         public static bool Delete(string key)     74         {     75             if (mc.KeyExists(key))     76             {     77                 return mc.Delete(key);     78      79             }     80             return false;     81         }     82          83     }      

至此已全部完成。 

  作者:Jeremy.Wu

  出處:https://www.cnblogs.com/jeremywucnblog/

  本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,否則保留追究法律責任的權利。