dengwen3 发表于 2015-9-1 08:16:44

Memcached遍历Key

前段时间XX升级之后出了点小问题,最后定位到是缓存数据格式变动造成的。当时就想要个工具去把memcached里的key拿出来看,之后虽然没有用上,但自己还是写了个,以备后用。

目前功能比较简单,只是遍历所有的key,稍加修改可以 1)取出指定格式(正则等)的key;2)显示value。交互可以更好一点:)








1 # -*- coding:utf-8 -*-
2import telnetlib
3import re
4def send(tn, cmd):
5   tn.write(cmd + "\r\n")
6   return tn.read_until("END\r\n")
7 HOST = "localhost"
8 PORT = 31211
9 tn = telnetlib.Telnet(HOST, PORT)
10 slabs = send(tn, "stats slabs")
11 chunk_pattern = "STAT (?P<type>\d+):chunk_size \d+\r\nSTAT \d+:chunks_per_page \d+\r\nSTAT \d+:total_pages \d+\r\nSTAT \d+:total_chunks (?P<total>\d+)\r\nSTAT \d+:used_chunks \d+\r\nSTAT \d+:free_chunks \d+\r\nSTAT \d+:free_chunks_end \d+\r\n"
12 key_pattern = "ITEM (\S+) \[(\d+) b; (\d+) s\]"
13 ret = re.findall(chunk_pattern, slabs)
14 cnt = 0
15import datetime
16for obj in ret:
17   cmd = "stats cachedump %s %s" % (obj, obj)
18   dump = send(tn, cmd)
19   keys = re.findall(key_pattern, dump)
20   for key in keys:
21         print "%s, %s, %s" % (key, key, datetime.datetime.fromtimestamp(float(key)))
  
ps: 网上已经有很多类似实现,好吧,我out了。
  2011-04-08更新:stats cachedump 输出最多为2MB,超出部分无法得到,这个时间只能显示前边部分key:(。还没看到其他命令可以获取。



    // 留意此值为回送内容的最大字节数,当回送内容达到2M时,即使没有达到用户想要的item数也会返回
int memlimit = 2*1024*1024;
……
// !!! alert:回送内容最多为2M
if (bufcurr + len + 6 > memlimit)/* 6 is END\r\n\0 */
break;
……

  9号晚在google上搜索别人的实现,找到一个Xmemcached客户端,在1.2.2版本后支持遍历所有Key。大喜,但快速阅读相关部分代码后发现一样存在这个问题,跟作者确认过了。附上邮件中的部分内容。
  
原因是:stats cachedump限制了输出的最大字节数为2M,当某一slab class里的item比较多时,该命令会在输出超过2M前返回。除了key的内容以后,cachedump每条信息需要至少5+2+1+4+10+5=27个字节,贪心的情况下key长度应该为3个字节(理论值),总共30个字节,所以最大可显示的key数量不超过69904.9(理论值)个。
页: [1]
查看完整版本: Memcached遍历Key