public static ICachedumpOperationResult Cachedump(this MemcachedClient client, int slab = 1, int limit = 0) { #region 反射获取 IServerPool 属性值 Type t = client.GetType(); PropertyInfo prop_Pool = t.GetProperty("Pool", BindingFlags.Instance | BindingFlags.NonPublic); PropertyInfo prop_KeyTransformer = t.GetProperty("KeyTransformer", BindingFlags.Instance | BindingFlags.NonPublic); IServerPool pool = prop_Pool.GetValue(client) as IServerPool; IMemcachedKeyTransformer keyTransformer = prop_KeyTransformer.GetValue(client) as IMemcachedKeyTransformer; #endregion string key = string.Format("{0} {1}", slab, limit); var hashedKey = keyTransformer.Transform(key.Replace(" ", "_")); var node = pool.Locate(hashedKey); ICachedumpOperationResultFactory CachedumpOperationResultFactory = new DefaultCachedumpOperationResultFactory(); var result = CachedumpOperationResultFactory.Create(); if (node != null) { var command = new CachedumpOperation(key); var commandResult = node.Execute(command); if (commandResult.Success) { result.Value = new Dictionary <string, string>(); command.Result.ForEach(item => { //item is: //ITEM testKey2 [3 b; 1600335168 s] //ITEM key_name [value_length b; expire_time | access_time s] // 0 1 2 3 4 5 //1.2.2- 访问时间(timestamp) //1.2.4+ 过期时间(timestamp) //如果是永不过期的key,expire_time会显示为服务器启动的时间 string[] parts = item.Split(' '); result.Value.Add(parts[1], string.Join(" ", parts, 2, parts.Length - 2)); }); result.Pass(); return(result); } else { commandResult.Combine(result); return(result); } } result.Fail("Unable to locate node"); return(result); }
protected override bool ExecuteAction() { // {hashed key -> normal key}: will be used when mapping the returned items back to the original keys Dictionary <string, string> hashedToReal = new Dictionary <string, string>(StringComparer.Ordinal); // {normal key -> hashed key}: we have to hash all keys anyway, so we better cache them to improve performance instead of doing the hashing later again Dictionary <string, string> realToHashed = new Dictionary <string, string>(StringComparer.Ordinal); IMemcachedKeyTransformer transformer = ServerPool.KeyTransformer; // and store them with the originals so we can map the returned items // to the original keys foreach (string s in keys) { string hashed = transformer.Transform(s); hashedToReal[hashed] = s; realToHashed[s] = hashed; } // map each key to the appropriate server in the pool IDictionary <MemcachedNode, IList <string> > splitKeys = ServerPool.SplitKeys(keys); // we'll open 1 socket for each server List <PooledSocket> sockets = new List <PooledSocket>(); try { // send a 'gets' to each server foreach (KeyValuePair <MemcachedNode, IList <string> > kp in splitKeys) { // gets <keys> // // keys: key key key key string[] command = new string[kp.Value.Count + 1]; command[0] = "gets"; kp.Value.CopyTo(command, 1); for (int i = 1; i < command.Length; i++) { command[i] = realToHashed[command[i]]; } PooledSocket socket = kp.Key.Acquire(); if (socket == null) { continue; } sockets.Add(socket); socket.SendCommand(String.Join(" ", command)); } Dictionary <string, object> retval = new Dictionary <string, object>(StringComparer.Ordinal); Dictionary <string, ulong> cas = new Dictionary <string, ulong>(StringComparer.Ordinal); // process each response and build a dictionary from the results foreach (PooledSocket socket in sockets) { try { GetResponse r; while ((r = GetHelper.ReadItem(socket)) != null) { string originalKey = hashedToReal[r.Key]; retval[originalKey] = ServerPool.Transcoder.Deserialize(r.Item); cas[originalKey] = r.CasValue; } } catch (NotSupportedException) { throw; } catch (Exception e) { log.Error(e); } } result = retval; casValues = cas; } finally { foreach (PooledSocket socket in sockets) { ((IDisposable)socket).Dispose(); } } return(true); }