asp.net (C #) Traversal Memcached Cache Objects _ Practical Tips

Source: Internet
Author: User
Tags memcached trim
Stats command

Traversing memcached Cache Objects (C #) reproduced in the Grass church
For performance reasons, memcached does not provide traversal functionality, but we can get all of the cached objects through the following two stats commands.
1, stats items

Displays the number of item in each slab.
2, stats cachedump slab_id limit_num
Displays the first Limit_num key list in a slab display format: ITEM key_name [Value_length b; expire_time|access_time S]
In addition to the top two, memcached also provides the following command:

3, stats
4, stats reset
5, stats malloc
6, stats maps
7, stats sizes
8, stats Slabs
9, stats detail [On|off|dump]
The use of the command is not to say, please google. There is a chance to write about memcached data storage and memory allocation.

Add cache
Add several key locally, as follows:

Program implementation
Because you want to call it in C #, you need the client to execute the STATS command, which can refer directly to the implementation in DiscuzNT3.0.
Discuznt Download Address: http://download.comsenz.com/DiscuzNT/src/
After downloading the program, find these two classes in the Discuz.cache project: MemCached.cs and MemCachedClient.cs.
The methods we need to use are:
Memcached.getstats
Code
Copy Code code as follows:

<summary>
Get server-side cached data information
</summary>
<param name= "serverarraylist" > List of services to access </param>
<returns> return information </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";
Convert Stats Command parameters
Switch (Statscommand)
{
Case Stats.reset: {commandstr = "Stats Reset";
Case Stats.malloc: {commandstr = "Stats Malloc";
Case Stats.maps: {commandstr = "Stats Maps";
Case stats.sizes: {commandstr = "Stats sizes";
Case Stats.slabs: {commandstr = "Stats slabs";
Case Stats.items: {commandstr = "Stats";
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";
}
Load return value
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;
}

Memcachedclient.stats
Code
Copy Code code as follows:

Public Hashtable Stats (ArrayList servers, string command)
{
Get Sockiopool Instance
Sockiopool pool = sockiopool.getinstance (_poolname);
return FALSE if unable to get Sockio obj
if (pool = = null)
{
if (log. iserrorenabled)
//{
Log. Error (getlocalizedstring ("Unable to get Socket pool"));
//}
return null;
}
Get all servers and iterate over them
if (servers = null)
Servers = pool. Servers;
If no servers, then return early
if (servers = NULL | | servers. Count <= 0)
{
if (log. iserrorenabled)
//{
Log. Error (getlocalizedstring ("Stats no Servers"));
//}
return null;
}
Array of stats Hashtables
Hashtable statsmaps = new Hashtable ();
for (int i = 0; i < servers. Count; i++)
{
Sockio sock = pool. Getconnection ((String) servers[i]);
if (sock = null)
{
if (log. iserrorenabled)
//{
Log. Error (getlocalizedstring ("Unable to connect"). Replace ("$ $Server $$", Servers[i]. ToString ()));
//}
Continue
}
Build command
Command = Discuz.Common.Utils.StrIsNullOrEmpty (command)? "stats\r\n": Command + "\ r \ n";
Try
{
Sock. Write (UTF8Encoding.UTF8.GetBytes (command));
Sock. Flush ();
Map to hold key value pairs
Hashtable stats = new Hashtable ();
Loop over results
while (true)
{
String line = sock. ReadLine ();
if (log. isdebugenabled)
//{
Log. Debug (getlocalizedstring ("Stats line"). Replace ("$ $Line $$", line));
//}
If line. StartsWith (STATS))
{
string[] Info = line. Split (")";
String key = Info[1];
String val = info[2];
if (log. isdebugenabled)
//{
Log. Debug (getlocalizedstring ("stats success"). Replace ("$ $Key $$", Key). Replace ("$ $Value $$", Val));
//}
stats[key] = val;
}
else if (end = line)
{
Finish when we are end from server
if (log. isdebugenabled)
//{
Log. Debug (getlocalizedstring ("stats finished"));
//}
Break
}
statsmaps[Servers[i]] = stats;
}
}
catch//(IOException e)
{
if (log. iserrorenabled)
//{
Log. Error (getlocalizedstring ("Stats IOException"), e);
//}
Try
{
Sock. Trueclose ();
}
catch//(IOException)
{
if (log. iserrorenabled)
//{
Log. Error (Getlocalizedstring ("failed to close some socket"). Replace ("$ $Socket $$", sock. ToString ()));
//}
}
sock = null;
}
if (sock!= null)
Sock. Close ();
}
return statsmaps;
}

With these two methods we can get the cached items in the memcached.
The basic idea is to get the cache all the item (stats items), and then through the Itemid out of CacheKey and Cachevalue (stats cachedump)
The program is implemented as follows:
Copy Code code as follows:

private void GetItems ()
{
ArrayList Itemarr = new ArrayList ();
ArrayList ArrayList = new ArrayList ();
StringBuilder sb = new StringBuilder ();
foreach (string server in Memcachedmanager.serverlist)
{
Arraylist.add (server);
}
ArrayList arr = memcachedmanager.getstats (ArrayList, MemCachedManager.Stats.Items, NULL);
foreach (String A in arr)
{
string[] Tmparr = A.split (': ');
if (Tmparr. Length > 1)
{
int item_id = 0;
Int. TryParse (Tmparr[1], out item_id);
bool find = false;
foreach (int item in Itemarr)
{
if (item = = item_id)
find = true;
}
if (!find && item_id > 0 && item_id!= 11211)
Itemarr. ADD (ITEM_ID);
}
}
foreach (int item in Itemarr)
{
Sb. Append ("item" + Item + "<br/>");
ArrayList Cachearr = Memcachedmanager.getstats (ArrayList, MemCachedManager.Stats.CachedDump, "" + Item + "10");
foreach (string cache in Cachearr)
{
Sb. Append (cache);
Sb. Append ("<br/>");
}
}
Response.Write (sb.) ToString ());
}

To run the program:

Why is there no output cache entry?

Bugs in the DiscuzNT3.0

So I looked for and found that it was a bug in the DiscuzNT3.0.

In Memcachedclient.stats, there is a piece of code like this:
Copy Code code as follows:

If line. StartsWith (STATS))
{
string[] Info = line. Split (")";
String key = Info[1];
String val = info[2];
stats[key] = val;

}
else if (end = line)
{
Break
}

The original is to ignore the stats cachedump result is the beginning of the item, so there is nothing output. Simple changes:
Copy Code code as follows:

If line. StartsWith (STATS))
{
string[] Info = line. Split (")";
String key = Info[1];
String val = info[2];
stats[key] = val;

}
else if line. StartsWith ("ITEM"))
{
string[] Info = line. Split (' [');
String key = Info[0]. Split (") [1];
string val = "[" + info[1];

Stats[key] = val;
}
else if (end = line)
{
Break
}

Look at the output again, the display is normal.
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.