一、Linux下MemCached安裝和啟動
如果是centos可以yum安裝
# yum install libevent-devel
如果不支援yum的系統,可以這樣裝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
繼續安裝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
安裝完後啟動memcached並分配1024m記憶體
/usr/local/memcached/bin/memcached -d -m 1024 –l 10.32.33.120 -p 11211 -u root
-d選項是啟動一個守護進程,
-m是分配給Memcache使用的記憶體數量,單位是MB,我這裡是10MB,
-u是運行Memcache的使用者,我這裡是root,
-l是監聽的伺服器IP地址,如果有多個地址的話,我這裡指定了伺服器的IP地址10.32.33.120,
-p是設定Memcache監聽的連接埠,我這裡設定了12000,最好是1024以上的連接埠,
-c選項是最大啟動並執行並發串連數,預設是1024,我這裡設定了256,按照你伺服器的負載量來設定,
-P是設定儲存Memcache的pid檔案,我這裡是儲存在 /tmp/memcached.pid,
將memcached加入啟動項
# 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
儲存退出
查看是否啟動memcached
擷取運行狀態:echo stats | nc 10.32.33.120 11211(可以查看出pid) 或使用ps -ef|grep memcached
如果要結束Memcache進程,執行:
# kill `cat /tmp/memcached.pid`
也可以
#kill –9 進程號
二、串連到 memcached
串連到 memcached:
telnet ip 連接埠,如telnet 10.32.33.120 11211
stats查看狀態,flush_all:清楚緩衝
查看memcached狀態的基本命令,通過這個命令可以看到如下資訊:
STAT pid 22459 進程ID
STAT uptime 1027046 伺服器運行秒數
STAT time 1273043062 伺服器當前unix時間戳記
STAT version 1.4.4 伺服器版本
STAT pointer_size 64 作業系統字大小(這台伺服器是64位的)
STAT rusage_user 0.040000 進程累計使用者時間
STAT rusage_system 0.260000 進程累計系統時間
STAT curr_connections 10 當前開啟串連數
STAT total_connections 82 曾開啟的串連總數
STAT connection_structures 13 伺服器分配的串連結構數
STAT cmd_get 54 執行get命令總數
STAT cmd_set 34 執行set命令總數
STAT cmd_flush 3 指向flush_all命令總數
STAT get_hits 9 get叫用次數
STAT get_misses 45 get未叫用次數
STAT delete_misses 5 delete未叫用次數
STAT delete_hits 1 delete叫用次數
STAT incr_misses 0 incr未叫用次數
STAT incr_hits 0 incr叫用次數
STAT decr_misses 0 decr未叫用次數
STAT decr_hits 0 decr叫用次數
STAT cas_misses 0 cas未叫用次數
STAT cas_hits 0 cas叫用次數
STAT cas_badval 0 使用擦拭次數
STAT auth_cmds 0
STAT auth_errors 0
STAT bytes_read 15785 讀取位元組總數
STAT bytes_written 15222 寫入位元組總數
STAT limit_maxbytes 1048576 分配的記憶體數(位元組)
STAT accepting_conns 1 目前接受的連結數
STAT listen_disabled_num 0
STAT threads 4 線程數
STAT conn_yields 0
STAT bytes 0 儲存item位元組數
STAT curr_items 0 item個數
STAT total_items 34 item總數
STAT evictions 0 為擷取空間刪除item的總數
三、c#調用
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 靜態方法和屬性 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;//初始化連結數 pool.MinConnections = memCachedConfigInfo.MinConnections;//最少連結數 pool.MaxConnections = memCachedConfigInfo.MaxConnections;//最大串連數 pool.SocketConnectTimeout = memCachedConfigInfo.SocketConnectTimeout;//Socket連結逾時時間 pool.SocketTimeout = memCachedConfigInfo.SocketTimeout;// Socket逾時時間 pool.MaintenanceSleep = memCachedConfigInfo.MaintenanceSleep;//維護線程休息時間 pool.Failover = memCachedConfigInfo.FailOver; //失效轉移(一種備份操作模式) pool.Nagle = memCachedConfigInfo.Nagle;//是否用nagle演算法啟動socket pool.HashingAlgorithm = HashingAlgorithm.NewCompatibleHash; pool.Initialize(); mc = new MemcachedClient(); mc.PoolName = memCachedConfigInfo.PoolName; mc.EnableCompression = false; } /// <summary> /// 快取服務器地址清單 /// </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(為了方便擴充其他的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> /// 到期時間,單位:秒 /// </summary> int TimeOut { set;get;} }}
MemCached.cs類
using System;using System.Web;using System.Collections;using System.Web.Caching;namespace Plugin.Cache{/// <summary>/// 預設緩衝管理類,預設用memcached/// </summary> public class MemCached : ICacheStrategy{/// <summary> /// 設定到期相對時間[單位: 秒] /// </summary> public int TimeOut { set; get; }/// <summary>/// 加入當前對象到緩衝中/// </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">對象的關鍵字</param> public virtual void RemoveObject(string objId){ if (MemCachedManager.CacheClient.KeyExists(objId)) MemCachedManager.CacheClient.Delete(objId);}/// <summary>/// 返回一個指定的對象/// </summary>/// <param name="objId">對象的關鍵字</param>/// <returns>對象</returns> public virtual object RetrieveObject(string objId){ return MemCachedManager.CacheClient.Get(objId);} }}
實體類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> /// 初始化連結數 /// </summary> public int IntConnections { get { return _intConnections > 0 ? _intConnections : 3; } set { _intConnections = value; } } private int _minConnections; /// <summary> /// 最少連結數 /// </summary> public int MinConnections { get { return _minConnections > 0 ? _minConnections : 3; } set { _minConnections = value; } } private int _maxConnections; /// <summary> /// 最大串連數 /// </summary> public int MaxConnections { get { return _maxConnections > 0 ? _maxConnections : 5; } set { _maxConnections = value; } } private int _socketConnectTimeout; /// <summary> /// Socket連結逾時時間 /// </summary> public int SocketConnectTimeout { get { return _socketConnectTimeout > 1000 ? _socketConnectTimeout : 1000; } set { _socketConnectTimeout = value; } } private int _socketTimeout; /// <summary> /// socket逾時時間 /// </summary> public int SocketTimeout { get { return _socketTimeout > 1000 ? _maintenanceSleep : 3000; } set { _socketTimeout = value; } } private int _maintenanceSleep; /// <summary> /// 維護線程休息時間 /// </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演算法啟動socket /// </summary> public bool Nagle { get { return _nagle; } set { _nagle = value; } } }}
實現代碼完了,下面就是把設定檔memcached.config還原序列化成實體方法
用MemCachedConfig.cs實現設定檔的載入和讀取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>
使用時調用方法:
MemCachedConfig.LoadConfig(Server.MapPath("/config/memcached.config"));
這個方法通過LoadConfig把配置載入進來,還原序列化成MemCachedConfigInfo實體並放入私人靜態變數config 中,並通過GetConfig() 擷取config,然後MemCachedManager類通過private static MemCachedConfigInfo memCachedConfigInfo = MemCachedConfig.GetConfig();方法擷取到配置了。