前段时间XX升级之后出了点小问题,最后定位到是缓存数据格式变动造成的。当时就想要个工具去把memcached里的key拿出来看,之后虽然没有用上,但自己还是写了个,以备后用。
目前功能比较简单,只是遍历所有的key,稍加修改可以 1)取出指定格式(正则等)的key;2)显示value。交互可以更好一点:)
目前功能比较简单,只是遍历所有的key,稍加修改可以 1)取出指定格式(正则等)的key;2)显示value。交互可以更好一点:)
1
#
-*- coding:utf-8 -*-
2 import telnetlib
3 import re
4 def 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
15 import datetime
16 for obj in ret:
17 cmd = " stats cachedump %s %s " % (obj[0], obj[ 1 ])
18 dump = send(tn, cmd)
19 keys = re.findall(key_pattern, dump)
20 for key in keys:
21 print " %s, %s, %s " % (key[0], key[ 1 ], datetime.datetime.fromtimestamp(float(key[ 2 ])))
2 import telnetlib
3 import re
4 def 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
15 import datetime
16 for obj in ret:
17 cmd = " stats cachedump %s %s " % (obj[0], obj[ 1 ])
18 dump = send(tn, cmd)
19 keys = re.findall(key_pattern, dump)
20 for key in keys:
21 print " %s, %s, %s " % (key[0], key[ 1 ], datetime.datetime.fromtimestamp(float(key[ 2 ])))
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(理论值)个。