Linux下MemCached安裝及c#客戶端調(diào)用
一、Linux下MemCached安裝和啟動(dòng)
如果是centos可以yum安裝
# yum install libevent-devel
如果不支持yum的系統(tǒng),可以這樣裝libevent
# cd /usr/local/src
# wget http://www.monkey.org/~provos/libevent-1.4.12-stable.tar.gz
# tar vxf libevent-1.4.12-stable.tar.gz
# cd libevent-1.4.12
# ./configure --prefix=/usr/local/libevent
# make && make install
繼續(xù)安裝memcached
# cd /usr/local/src
# wget http://cloud.github.com/downloads/saberma/saberma.github.com/memcached-1.4.4.tar.gz
# tar vxf memcached-1.4.4.tar.gz
# cd memcached-1.4.4
# ./configure --prefix=/usr/local/memcached
# make && make install
安裝完后啟動(dòng)memcached并分配1024m內(nèi)存
/usr/local/memcached/bin/memcached -d -m 1024 –l 10.32.33.120 -p 11211 -u root
-d選項(xiàng)是啟動(dòng)一個(gè)守護(hù)進(jìn)程,
-m是分配給Memcache使用的內(nèi)存數(shù)量,單位是MB,我這里是10MB,
-u是運(yùn)行Memcache的用戶,我這里是root,
-l是監(jiān)聽的服務(wù)器IP地址,如果有多個(gè)地址的話,我這里指定了服務(wù)器的IP地址10.32.33.120,
-p是設(shè)置Memcache監(jiān)聽的端口,我這里設(shè)置了12000,最好是1024以上的端口,
-c選項(xiàng)是最大運(yùn)行的并發(fā)連接數(shù),默認(rèn)是1024,我這里設(shè)置了256,按照你服務(wù)器的負(fù)載量來設(shè)定,
-P是設(shè)置保存Memcache的pid文件,我這里是保存在 /tmp/memcached.pid,
將memcached加入啟動(dòng)項(xiàng)
# vi /etc/rc.d/rc.local
在最后加入
/usr/local/memcached/bin/memcached -d -m 1024 –l 10.32.33.120 -p 11211 -u root
按Esc鍵,再輸入
:wq
保存退出
查看是否啟動(dòng)memcached
獲取運(yùn)行狀態(tài):echo stats | nc 10.32.33.120 11211(可以查看出pid) 或使用ps -ef|grep memcached
如果要結(jié)束Memcache進(jìn)程,執(zhí)行:
# kill `cat /tmp/memcached.pid`
也可以
#kill –9 進(jìn)程號
二、連接到 memcached
連接到 memcached:
telnet ip 端口,如telnet 10.32.33.120 11211
stats查看狀態(tài),flush_all:清楚緩存
查看memcached狀態(tài)的基本命令,通過這個(gè)命令可以看到如下信息:
STAT pid 22459 進(jìn)程ID
STAT uptime 1027046 服務(wù)器運(yùn)行秒數(shù)
STAT time 1273043062 服務(wù)器當(dāng)前unix時(shí)間戳
STAT version 1.4.4 服務(wù)器版本
STAT pointer_size 64 操作系統(tǒng)字大小(這臺服務(wù)器是64位的)
STAT rusage_user 0.040000 進(jìn)程累計(jì)用戶時(shí)間
STAT rusage_system 0.260000 進(jìn)程累計(jì)系統(tǒng)時(shí)間
STAT curr_connections 10 當(dāng)前打開連接數(shù)
STAT total_connections 82 曾打開的連接總數(shù)
STAT connection_structures 13 服務(wù)器分配的連接結(jié)構(gòu)數(shù)
STAT cmd_get 54 執(zhí)行g(shù)et命令總數(shù)
STAT cmd_set 34 執(zhí)行set命令總數(shù)
STAT cmd_flush 3 指向flush_all命令總數(shù)
STAT get_hits 9 get命中次數(shù)
STAT get_misses 45 get未命中次數(shù)
STAT delete_misses 5 delete未命中次數(shù)
STAT delete_hits 1 delete命中次數(shù)
STAT incr_misses 0 incr未命中次數(shù)
STAT incr_hits 0 incr命中次數(shù)
STAT decr_misses 0 decr未命中次數(shù)
STAT decr_hits 0 decr命中次數(shù)
STAT cas_misses 0 cas未命中次數(shù)
STAT cas_hits 0 cas命中次數(shù)
STAT cas_badval 0 使用擦拭次數(shù)
STAT auth_cmds 0
STAT auth_errors 0
STAT bytes_read 15785 讀取字節(jié)總數(shù)
STAT bytes_written 15222 寫入字節(jié)總數(shù)
STAT limit_maxbytes 1048576 分配的內(nèi)存數(shù)(字節(jié))
STAT accepting_conns 1 目前接受的鏈接數(shù)
STAT listen_disabled_num 0
STAT threads 4 線程數(shù)
STAT conn_yields 0
STAT bytes 0 存儲item字節(jié)數(shù)
STAT curr_items 0 item個(gè)數(shù)
STAT total_items 34 item總數(shù)
STAT evictions 0 為獲取空間刪除item的總數(shù)
三、c#調(diào)用
MemCache管理操作類,MemCachedManager.cs文件:
using System;
using System.Collections;
using System.Data;
using System.Data.Common;
using System.IO;
using Memcached.ClientLibrary;
namespace Plugin.Cache
{
/// <summary>
/// MemCache管理操作類
/// </summary>
public sealed class MemCachedManager
{
#region 靜態(tài)方法和屬性
private static MemcachedClient mc = null;
private static SockIOPool pool = null;
private static string[] serverList = null;
private static MemCachedConfigInfo memCachedConfigInfo = MemCachedConfig.GetConfig();
#endregion
static MemCachedManager()
{
CreateManager();
}
private static void CreateManager()
{
serverList = memCachedConfigInfo.ServerList;
pool = SockIOPool.GetInstance(memCachedConfigInfo.PoolName);
pool.SetServers(serverList);
pool.InitConnections = memCachedConfigInfo.IntConnections;//初始化鏈接數(shù)
pool.MinConnections = memCachedConfigInfo.MinConnections;//最少鏈接數(shù)
pool.MaxConnections = memCachedConfigInfo.MaxConnections;//最大連接數(shù)
pool.SocketConnectTimeout = memCachedConfigInfo.SocketConnectTimeout;//Socket鏈接超時(shí)時(shí)間
pool.SocketTimeout = memCachedConfigInfo.SocketTimeout;// Socket超時(shí)時(shí)間
pool.MaintenanceSleep = memCachedConfigInfo.MaintenanceSleep;//維護(hù)線程休息時(shí)間
pool.Failover = memCachedConfigInfo.FailOver; //失效轉(zhuǎn)移(一種備份操作模式)
pool.Nagle = memCachedConfigInfo.Nagle;//是否用nagle算法啟動(dòng)socket
pool.HashingAlgorithm = HashingAlgorithm.NewCompatibleHash;
pool.Initialize();
mc = new MemcachedClient();
mc.PoolName = memCachedConfigInfo.PoolName;
mc.EnableCompression = false;
}
/// <summary>
/// 緩存服務(wù)器地址列表
/// </summary>
public static string[] ServerList
{
set
{
if (value != null)
serverList = value;
}
get { return serverList; }
}
/// <summary>
/// 客戶端緩存操作對象
/// </summary>
public static MemcachedClient CacheClient
{
get
{
if (mc == null)
CreateManager();
return mc;
}
}
public static void Dispose()
{
if (pool != null)
pool.Shutdown();
}
}
}
cache操作接口類ICacheStrategy.cs(為了方便擴(kuò)展其他的cache):
using System;
using System.Text;
namespace Plugin.Cache
{
/// <summary>
/// 公共緩存策略接口
/// </summary>
public interface ICacheStrategy
{
/// <summary>
/// 添加指定ID的對象
/// </summary>
/// <param name="objId">緩存鍵</param>
/// <param name="o">緩存對象</param>
void AddObject(string objId, object o);
/// <summary>
/// 移除指定ID的對象
/// </summary>
/// <param name="objId">緩存鍵</param>
void RemoveObject(string objId);
/// <summary>
/// 返回指定ID的對象
/// </summary>
/// <param name="objId">緩存鍵</param>
/// <returns></returns>
object RetrieveObject(string objId);
/// <summary>
/// 到期時(shí)間,單位:秒
/// </summary>
int TimeOut { set;get;}
}
}
MemCached.cs類
using System;
using System.Web;
using System.Collections;
using System.Web.Caching;
namespace Plugin.Cache
{
/// <summary>
/// 默認(rèn)緩存管理類,默認(rèn)用memcached
/// </summary>
public class MemCached : ICacheStrategy
{
/// <summary>
/// 設(shè)置到期相對時(shí)間[單位: 秒]
/// </summary>
public int TimeOut { set; get; }
/// <summary>
/// 加入當(dāng)前對象到緩存中
/// </summary>
/// <param name="objId">對象的鍵值</param>
/// <param name="o">緩存的對象</param>
public virtual void AddObject(string objId, object o)
{
if (TimeOut > 0)
{
MemCachedManager.CacheClient.Set(objId, o, System.DateTime.Now.AddSeconds(TimeOut));
}
else
{
MemCachedManager.CacheClient.Set(objId, o);
}
}
/// <summary>
/// 刪除緩存對象
/// </summary>
/// <param name="objId">對象的關(guān)鍵字</param>
public virtual void RemoveObject(string objId)
{
if (MemCachedManager.CacheClient.KeyExists(objId))
MemCachedManager.CacheClient.Delete(objId);
}
/// <summary>
/// 返回一個(gè)指定的對象
/// </summary>
/// <param name="objId">對象的關(guān)鍵字</param>
/// <returns>對象</returns>
public virtual object RetrieveObject(string objId)
{
return MemCachedManager.CacheClient.Get(objId);
}
}
}
實(shí)體類MemCachedConfigInfo.cs
using Yintai.Plugin.Common;
/// <summary>
/// MemCached配置信息類文件
/// </summary>
namespace Plugin
{
public class MemCachedConfigInfo
{
private string[] _serverList;
/// <summary>
/// 鏈接地址
/// </summary>
public string[] ServerList
{
get { return _serverList; }
set { _serverList = value; }
}
private string _poolName;
/// <summary>
/// 鏈接池名稱
/// </summary>
public string PoolName
{
get { return string.IsNullOrEmpty(_poolName) ? "Yintai.Plugin.Cache.MemCached" : _poolName; }
set { _poolName = value; }
}
private int _intConnections;
/// <summary>
/// 初始化鏈接數(shù)
/// </summary>
public int IntConnections
{
get { return _intConnections > 0 ? _intConnections : 3; }
set { _intConnections = value; }
}
private int _minConnections;
/// <summary>
/// 最少鏈接數(shù)
/// </summary>
public int MinConnections
{
get { return _minConnections > 0 ? _minConnections : 3; }
set { _minConnections = value; }
}
private int _maxConnections;
/// <summary>
/// 最大連接數(shù)
/// </summary>
public int MaxConnections
{
get { return _maxConnections > 0 ? _maxConnections : 5; }
set { _maxConnections = value; }
}
private int _socketConnectTimeout;
/// <summary>
/// Socket鏈接超時(shí)時(shí)間
/// </summary>
public int SocketConnectTimeout
{
get { return _socketConnectTimeout > 1000 ? _socketConnectTimeout : 1000; }
set { _socketConnectTimeout = value; }
}
private int _socketTimeout;
/// <summary>
/// socket超時(shí)時(shí)間
/// </summary>
public int SocketTimeout
{
get { return _socketTimeout > 1000 ? _maintenanceSleep : 3000; }
set { _socketTimeout = value; }
}
private int _maintenanceSleep;
/// <summary>
/// 維護(hù)線程休息時(shí)間
/// </summary>
public int MaintenanceSleep
{
get { return _maintenanceSleep > 0 ? _maintenanceSleep : 30; }
set { _maintenanceSleep = value; }
}
private bool _failOver;
/// <summary>
/// 鏈接失敗后是否重啟,詳情參見http://baike.baidu.com/view/1084309.htm
/// </summary>
public bool FailOver
{
get { return _failOver; }
set { _failOver = value; }
}
private bool _nagle;
/// <summary>
/// 是否用nagle算法啟動(dòng)socket
/// </summary>
public bool Nagle
{
get { return _nagle; }
set { _nagle = value; }
}
}
}
實(shí)現(xiàn)代碼完了,下面就是把配置文件memcached.config反序列化成實(shí)體方法
用MemCachedConfig.cs實(shí)現(xiàn)配置文件的載入和讀取LoadConfig是載入配置,SetConfig是保存配置,GetConfig是獲取配置,其中用了了序列化和反序列化
MemCachedConfig.cs文件如下:
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Text;
using System.Web;
using Plugin.Cache;
using Plugin.Common;
namespace Plugin
{
public class MemCachedConfig
{
private static object _lockHelper = new object();
private static MemCachedConfigInfo config = null;
public static void LoadConfig(string configfilepath)
{
if (config == null)
{
lock (_lockHelper)
{
if (config == null)
{
config = (MemCachedConfigInfo)SerializationHelper.Load(typeof(MemCachedConfigInfo), configfilepath);
}
}
}
}
/// <summary>
/// 獲取配置
/// </summary>
/// <param name="anConfig"></param>
public static MemCachedConfigInfo GetConfig()
{
return config;
}
#region 私有方法
public static void SetConfig(MemCachedConfigInfo verifyImageServiceInfoList, string configfilepath)
{
SerializationHelper.Save(verifyImageServiceInfoList, configfilepath);
}
#endregion
}
}
SerializationHelper.cs代碼如下:
using System;
using System.IO;
using System.Xml.Serialization;
using System.Xml;
using System.Collections.Generic;
using System.Text;
namespace Plugin.Common
{
/// <summary>
/// SerializationHelper 的摘要說明。
/// </summary>
public class SerializationHelper
{
private SerializationHelper()
{}
private static Dictionary<int, XmlSerializer> serializer_dict = new Dictionary<int, XmlSerializer>();
public static XmlSerializer GetSerializer(Type t)
{
int type_hash = t.GetHashCode();
if (!serializer_dict.ContainsKey(type_hash))
serializer_dict.Add(type_hash, new XmlSerializer(t));
return serializer_dict[type_hash];
}
/// <summary>
/// 反序列化
/// </summary>
/// <param name="type">對象類型</param>
/// <param name="filename">文件路徑</param>
/// <returns></returns>
public static object Load(Type type, string filename)
{
FileStream fs = null;
try
{
// open the stream...
fs = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
XmlSerializer serializer = new XmlSerializer(type);
return serializer.Deserialize(fs);
}
catch(Exception ex)
{
throw ex;
}
finally
{
if(fs != null)
fs.Close();
}
}
/// <summary>
/// 序列化
/// </summary>
/// <param name="obj">對象</param>
/// <param name="filename">文件路徑</param>
public static bool Save(object obj, string filename)
{
bool success = false;
FileStream fs = null;
// serialize it...
try
{
fs = new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.ReadWrite);
XmlSerializer serializer = new XmlSerializer(obj.GetType());
serializer.Serialize(fs, obj);
success = true;
}
catch(Exception ex)
{
throw ex;
}
finally
{
if(fs != null)
fs.Close();
}
return success;
}
/// <summary>
/// xml序列化成字符串
/// </summary>
/// <param name="obj">對象</param>
/// <returns>xml字符串</returns>
public static string Serialize(object obj)
{
string returnStr = "";
XmlSerializer serializer = GetSerializer(obj.GetType());
MemoryStream ms = new MemoryStream();
XmlTextWriter xtw = null;
StreamReader sr = null;
try
{
xtw = new System.Xml.XmlTextWriter(ms, Encoding.UTF8);
xtw.Formatting = System.Xml.Formatting.Indented;
serializer.Serialize(xtw, obj);
ms.Seek(0, SeekOrigin.Begin);
sr = new StreamReader(ms);
returnStr = sr.ReadToEnd();
}
catch (Exception ex)
{
throw ex;
}
finally
{
if (xtw != null)
xtw.Close();
if (sr != null)
sr.Close();
ms.Close();
}
return returnStr;
}
public static object DeSerialize(Type type, string s)
{
byte[] b = System.Text.Encoding.UTF8.GetBytes(s);
try
{
XmlSerializer serializer = GetSerializer(type);
return serializer.Deserialize(new MemoryStream(b));
}
catch (Exception ex)
{
throw ex;
}
}
}
}
最后配置文件類似這樣的:
<?xml version="1.0"?>
<MemCachedConfigInfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<ServerList>
<string>10.32.33.120:11211</string>
</ServerList>
<PoolName>Plugin.Cache.MemCached</PoolName>
<IntConnections>3</IntConnections>
<MinConnections>3</MinConnections>
<MaxConnections>5</MaxConnections>
<SocketConnectTimeout>1000</SocketConnectTimeout>
<SocketTimeout>30</SocketTimeout>
<MaintenanceSleep>30</MaintenanceSleep>
<FailOver>true</FailOver>
<Nagle>false</Nagle>
</MemCachedConfigInfo>
使用時(shí)調(diào)用方法:
MemCachedConfig.LoadConfig(Server.MapPath("/config/memcached.config"));
這個(gè)方法通過LoadConfig把配置加載進(jìn)來,反序列化成MemCachedConfigInfo實(shí)體并放入私有靜態(tài)變量config 中,并通過GetConfig() 獲取config,然后MemCachedManager類通過private static MemCachedConfigInfo memCachedConfigInfo = MemCachedConfig.GetConfig();方法獲取到配置了。

浙公網(wǎng)安備 33010602011771號