是一緩存,能夠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