当然我还在这个管理操作类中添加了几个方法分别用于检测当前有效的分布式缓存服务器的列表,向指定(或全部) 缓存服务器发送特定stats命令来获取当前缓存服务器上的数据信息和内存分配信息等,相应的方法如下(详情见注释): /// <summary>
/// 获取当前缓存键值所存储在的服务器 /// </summary> /// <param name="key">当前缓存键</param> /// <returns>当前缓存键值所存储在的服务器</returns> public static string GetSocketHost(string key) { string hostName = ""; SockIO sock = null; try { sock = SockIOPool.GetInstance(memCachedConfigInfo.PoolName).GetSock(key); if (sock != null) { hostName = sock.Host; } } finally { if (sock != null) sock.Close(); } return hostName; } /// <summary> /// 获取有效的服务器地址 /// </summary> /// <returns>有效的服务器地</returns> public static string[] GetConnectedSocketHost() { SockIO sock = null; string connectedHost = null; foreach (string hostName in serverList) { if (!Discuz.Common.Utils.StrIsNullOrEmpty(hostName)) { try { sock = SockIOPool.GetInstance(memCachedConfigInfo.PoolName).GetConnection(hostName); if (sock != null) { connectedHost = Discuz.Common.Utils.MergeString(hostName, connectedHost); } } finally { if (sock != null) sock.Close(); } } } return Discuz.Common.Utils.SplitString(connectedHost, ","); } /// <summary> /// 获取服务器端缓存的数据信息 /// </summary> /// <returns>返回信息</returns> public static ArrayList GetStats() { ArrayList arrayList = new ArrayList(); foreach (string server in serverList) { arrayList.Add(server); } return GetStats(arrayList, Stats.Default, null); } /// <summary> /// 获取服务器端缓存的数据信息 /// </summary> /// <param name="serverArrayList">要访问的服务列表</param> /// <returns>返回信息</returns> public static ArrayList GetStats(ArrayList serverArrayList, Stats statsCommand, string param) { ArrayList statsArray = new ArrayList(); param = Utils.StrIsNullOrEmpty(param) ? "" : param.Trim().ToLower(); string commandstr = "stats"; //转换stats命令参数 switch (statsCommand) { case Stats.Reset: { commandstr = "stats reset"; break; } case Stats.Malloc: { commandstr = "stats malloc"; break; } case Stats.Maps: { commandstr = "stats maps"; break; } case Stats.Sizes: { commandstr = "stats sizes"; break; } case Stats.Slabs: { commandstr = "stats slabs"; break; } case Stats.Items: { commandstr = "stats"; break; } case Stats.CachedDump: { string[] statsparams = Utils.SplitString(param, " "); if(statsparams.Length == 2) if(Utils.IsNumericArray(statsparams)) commandstr = "stats cachedump " + param; break; } case Stats.Detail: { if(string.Equals(param, "on") || string.Equals(param, "off") || string.Equals(param, "dump")) commandstr = "stats detail " + param.Trim(); break; } default: { commandstr = "stats"; break; } } //加载返回值 Hashtable stats = MemCachedManager.CacheClient.Stats(serverArrayList, commandstr); foreach (string key in stats.Keys) { statsArray.Add(key); Hashtable values = (Hashtable)stats[key]; foreach (string key2 in values.Keys) { statsArray.Add(key2 + ":" + values[key2]); } } return statsArray; } /// <summary> /// Stats命令行参数 /// </summary> public enum Stats { /// <summary> /// stats : 显示服务器信息, 统计数据等 /// </summary> Default = 0, /// <summary> /// stats reset : 清空统计数据 /// </summary> Reset = 1, /// <summary> /// stats malloc : 显示内存分配数据 /// </summary> Malloc = 2, /// <summary> /// stats maps : 显示"/proc/self/maps"数据 /// </summary> Maps =3, /// <summary> /// stats sizes /// </summary> Sizes = 4, /// <summary> /// stats slabs : 显示各个slab的信息,包括chunk的大小,数目,使用情况等 /// </summary> Slabs = 5, /// <summary> /// stats items : 显示各个slab中item的数目和最老item的年龄(最后一次访问距离现在的秒数) /// </summary> Items = 6, /// <summary> /// stats cachedump slab_id limit_num : 显示某个slab中的前 limit_num 个 key 列表 /// </summary> CachedDump =7, /// <summary> /// stats detail [on|off|dump] : 设置或者显示详细操作记录 on:打开详细操作记录 off:关闭详细操作记录 dump: 显示详细操作记录(每一个键值get,set,hit,del的次数) /// </summary> Detail = 8 } 当然在配置初始化缓存链接池时使用了配置文件方式(memcached.config)来管理相关参数,其info信息 类说明如下(Discuz.Config/MemCachedConfigInfo.cs): /// <summary>
/// MemCached配置信息类文件 /// </summary> public class MemCachedConfigInfo : IConfigInfo { private bool _applyMemCached; /// <summary> /// 是否应用MemCached /// </summary> public bool ApplyMemCached { get { return _applyMemCached; } set { _applyMemCached = value; } } private string _serverList; /// <summary> /// 链接地址 /// </summary> public string ServerList { get { return _serverList; } set { _serverList = value; } } private string _poolName; /// <summary> /// 链接池名称 /// </summary> public string PoolName { get { return Utils.StrIsNullOrEmpty(_poolName) ? "DiscuzNT_MemCache" : _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的主要性能都是通过这些参数来决定的,大家 应根据自己公司产品和应用的实际情况配置相应的数值。 (责任编辑:admin) |