最近在看一些Memcached的资料,在.net下它的客户端比php等其他语言要少,我选择了EnyimMemcached(http://www.codeplex.com/enyimmemcached/ ),主要是前几天看大众点评网技术部博客时,发现他们用的是这个客户端(http://it.dianping.com/using_attribute_and_piab_to_hybrid_memcached_and_data_access_layer.htm )
Memcached本身对外提供的命令不多,也就add、get、set、incr、decr、replace、delete、stats等几个,客户端对这些操作进行了封装,总体来说调用还是很简单的。
初看了下EnyimMemcached结构,所有的操作都从Operation类继承,每个子类都实现自己的ExcuteAction
操作:新窗口查看图片
所有的操作都由MemCachedClient这个门面提供
操作:新窗口查看图片
在使用过程中,我需要遍历当前缓存,获取所有键值,EnyimMemCached却没有提供遍历的方法。在网上查了下,http://www.cnblogs.com/sunli/archive/2008/11/01/1324153.html 提供了遍历的思路,很简单,用"stats item"与"stats cachedump 1 0"命令即可实现遍历,我要做的只是把两个命令封装成上面提到的Operation,下面是实现代码:
using System; using System.Collections; using System.Collections.Generic; using System.Text; using System.Text.RegularExpressions; namespace Enyim.Caching.Memcached { /// <summary> /// 扩展的获取所有键值操作 by wm /// </summary> internal class CacheDumpOperation : Operation { public CacheDumpOperation(ServerPool pool, string regex) : base(pool) { this.regexquery = regex; } private ArrayList results; /// <summary> /// 结果键值集合 /// </summary> public ArrayList Results { get { return results; } } private string regexquery = ""; /// <summary> /// 查询条件正则表达式 /// </summary> public string RegexQuery { get { return regexquery; } set { regexquery = value; } } protected override bool ExecuteAction() { List<string> lstParams = new List<string>(); ArrayList arrKeys = new ArrayList(); foreach (MemcachedNode server in this.ServerPool.WorkingServers) { using (PooledSocket ps = server.Acquire()) //step1 { if (ps != null) { ps.SendCommand("stats items"); while (true) { string line = ps.ReadResponse(); if (String.Compare(line, "END", StringComparison.Ordinal) == 0) break; if (line.Length < 6 || String.Compare(line, 0, "STAT ", 0, 5, StringComparison.Ordinal) != 0) { continue; } string para = line.Split(':')[1]; if (!lstParams.Contains(para)) { lstParams.Add(para); } } } } using (PooledSocket psDump = server.Acquire()) //step2 { if (psDump != null) { foreach (string para in lstParams) { psDump.SendCommand(string.Format("stats cachedump {0} {1}", para, 0)); while (true) { string lineDump = psDump.ReadResponse(); if (String.Compare(lineDump, "END", StringComparison.Ordinal) == 0) break; if (lineDump.Length < 6 || String.Compare(lineDump, 0, "ITEM ", 0, 5, StringComparison.Ordinal) != 0) { continue; } string key = lineDump.Split(' ')[1]; if (this.regexquery == "") { arrKeys.Add(key); } else { if (Regex.IsMatch(key, this.regexquery)) { arrKeys.Add(key); } } } } } } } this.results = arrKeys; return true; } } } </string></string>
在MemcachedClient中添加方法
/// <summary> /// 获取所有键值集合 /// </summary> /// <returns></returns> public System.Collections.ArrayList GetKeys() { using (CacheDumpOperation g = new CacheDumpOperation(this.pool, "")) { g.Execute(); return g.Results; } } /// <summary> /// 根据正则查找匹配缓存键值集合 /// </summary> /// <param name="regex"> /// <returns></returns> public System.Collections.ArrayList GetKeys(string regex) { using (CacheDumpOperation g = new CacheDumpOperation(this.pool, regex)) { g.Execute(); return g.Results; } }