程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> 淺談Memcached的應用

淺談Memcached的應用

編輯:關於.NET

是一緩存,能夠Set, Get value,哈哈,普通用法如下:

public User GetUser(int userId)
{
            UserInfo user = cacheService.Get("UserInfo:" + userId) as UserInfo;//cacheService是自定義的接口,具體的memcache實現代碼被隔離了
            if (user == null)
            {
                user = dao.GetUser(userId);
                cacheService.Set("UserInfo:" + userId, user);
            }
            return user;
}

在真正使用Memcached之前,需要先初始化它,如下:

string[] serverlist = { "192.168.1.11:11211", "192.168.1.12:11211", "192.168.1.13:11211" };//服務器可以是多個  
    
            //初始化池  
            SockIOPool pool = SockIOPool.GetInstance();
            pool.SetServers(serverlist);//設置連接池可用的cache服務器列表,server的構成形式是IP:PORT(如:127.0.0.1:11211)  
            pool.InitConnections = 3;//初始連接數  
            pool.MinConnections = 3;//最小連接數  
            pool.MaxConnections = 5;//最大連接數  
            pool.SocketConnectTimeout = 1000;//設置連接的套接字超時  
            pool.SocketTimeout = 3000;//設置套接字超時讀取  
            pool.MaintenanceSleep = 30;//設置維護線程運行的睡眠時間。如果設置為0,那麼維護線程將不會啟動,30就是每隔30秒醒來一次  
    
            //獲取或設置池的故障標志。  
            //如果這個標志被設置為true則socket連接失敗,將試圖從另一台服務器返回一個套接字如果存在的話。  
            //如果設置為false,則得到一個套接字如果存在的話。否則返回NULL,如果它無法連接到請求的服務器。  
            pool.Failover = true;
    
            pool.Nagle = false;//如果為false,對所有創建的套接字關閉Nagle的算法  
            pool.Initialize();

MemcachedProvider代碼:

public class MemcachedProvider : ICache
    {
        private MemcachedClient mc = new MemcachedClient();
        public void Set(string key, object o)
        {
            mc.Set(key, o);
        }
    
        public object Get(string key)
        {
            return mc.Get(key);
        }
    }

用法很簡單,下面說說它的一些限制:

每個key最多<=250長度

每個value最大<=1M(如果超過1M,則在C#端自己分解搞定)

沒有冗余機制,既:當某一台memcached服務器down掉後,數據就丟失了,不會自動平衡數據

示例的UML圖:

緩存的數據是通過hash後來分布到各台Memcache Server的,因此,假設每台Memcached Server都分別分配到4G內存的話,那我們的C#程序就能夠用到12G內存。這個說法其實不准確,能否用足這12G的內存,完全看MemcacheClient端的分布key的算法(上圖中左邊接口部分),等以後再深入研究這個算法。

下面來說說當某台memcached server down掉後的解決辦法(共3種解決方法):

用熱備節點

從配置文件裡去掉那台失效的memcached server的ip

增加一台Backup Memcached Server

一、用熱備節點

程序端不改變任何東西

當發現某memcached server down機後,啟動一台新memcached server,並且把新memcached server的IP修改為down機的IP(down掉的那台不要拿單獨修復)

這個辦法不利的地方是:在down掉和上線期間,緩存是沒有的,會throw exception,需要程序捕獲,並且當成null值來處理,會增加數據庫的壓力

二、從配置文件裡去掉那台失效的memcached server的ip

那就是修改配置文件了,然後再把down掉的server慢慢修復,等修復後再修改配置文件...

非常不好,光修改配置文件就要導致application reset了。不過當資源有限時,也只能這樣了。

查看本欄目

三、增加一台Backup Memcached Server

物理節點圖如下:

C#端:由原先的一個MemcachedClient客戶端變成了"MemcachedClient"和"BackupMemcachedClient"共同存在

Memcached server服務器端:增加一台Backup Memcached Server,這台server性能和內存都要高於其他三台memcached server的配置,這台server將保存所有的cache,因此性能要求高,尤其是網絡和內存。

先初始化這2個pool:

string[] serverlist = { "192.168.1.11:11211", "192.168.1.12:11211", "192.168.1.13:11211" };//普通Memcached服務器  
    
            //初始化池  
            SockIOPool pool = SockIOPool.GetInstance("NormalServers");                     //設置PoolName
            pool.SetServers(serverlist);//設置連接池可用的cache服務器列表,server的構成形式是IP:PORT(如:127.0.0.1:11211)  
            pool.InitConnections = 3;//初始連接數  
            pool.MinConnections = 3;//最小連接數  
            pool.MaxConnections = 5;//最大連接數  
            pool.SocketConnectTimeout = 1000;//設置連接的套接字超時  
            pool.SocketTimeout = 3000;//設置套接字超時讀取  
            pool.MaintenanceSleep = 30;//設置維護線程運行的睡眠時間。如果設置為0,那麼維護線程將不會啟動,30就是每隔30秒醒來一次  
    
            //獲取或設置池的故障標志。  
            //如果這個標志被設置為true則socket連接失敗,將試圖從另一台服務器返回一個套接字如果存在的話。  
            //如果設置為false,則得到一個套接字如果存在的話。否則返回NULL,如果它無法連接到請求的服務器。  
            pool.Failover = true;
    
            pool.Nagle = false;//如果為false,對所有創建的套接字關閉Nagle的算法  
            pool.Initialize();
    
    
            string[] backupServerlist = { "192.168.1.14:11211"};                         //Backup服務器
    
            //初始化池  
            SockIOPool backupPool = SockIOPool.GetInstance("BackupServers");             //設置PoolName
            backupPool.SetServers(backupServerlist);//設置連接池可用的cache服務器列表,server的構成形式是IP:PORT(如:127.0.0.1:11211)  
            backupPool.InitConnections = 3;//初始連接數  
            backupPool.MinConnections = 3;//最小連接數  
            backupPool.MaxConnections = 5;//最大連接數  
            backupPool.SocketConnectTimeout = 1000;//設置連接的套接字超時  
            backupPool.SocketTimeout = 3000;//設置套接字超時讀取  
            backupPool.MaintenanceSleep = 30;//設置維護線程運行的睡眠時間。如果設置為0,那麼維護線程將不會啟動,30就是每隔30秒醒來一次  
    
            //獲取或設置池的故障標志。  
            //如果這個標志被設置為true則socket連接失敗,將試圖從另一台服務器返回一個套接字如果存在的話。  
            //如果設置為false,則得到一個套接字如果存在的話。否則返回NULL,如果它無法連接到請求的服務器。  
            backupPool.Failover = true;
    
            backupPool.Nagle = false;//如果為false,對所有創建的套接字關閉Nagle的算法  
            backupPool.Initialize();

MemcachedProvider改為:

public class MemcachedProvider : ICache
    {
        private static MemcachedClient GetNormalServerClient()
        { 
            MemcachedClient mc = new MemcachedClient();
            mc.PoolName = "NormalServers";
            return mc;
        }
        private static MemcachedClient GetBackupServerClient()
        {
            MemcachedClient mc = new MemcachedClient();
            mc.PoolName = "BackupServers";
            return mc;
        }
            
        public void Set(string key, object o)
        {
            try
            {
                GetNormalServerClient().Set(key, o);
                GetBackupServerClient().Set(key, o);       //這個看情況改為異步執行
            }
            catch
            { 
                //notify or log
            }
        }
    
        public object Get(string key)
        {
            object o=null;
            try
            {
                o = GetNormalServerClient().Get(key);
            }
            catch
            {
                //notify or log
            }
            if (o != null)
                return o;
    
            try
            {
                o = GetBackupServerClient().Get(key);
            }
            catch
            {
                //notify or log
            }
    
            return o;
        }
    }

就這些吧。

作者:cnblogs Aaron

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved