memcached-tool
准确来讲这是一个Perl开发的脚本工具,它可以方便地获得memcached中的各种运行信息,如slab的使用情况 ,它将memcached的返回值整理成容易阅读的格式。使用方法也极其简单:
$ perl memcached-tool server_ip:prot option
例子:
perl memcached-tool 10.72.20.19:12001 stats
perl memcached-tool 10.72.20.19:12001 dump
perl memcached-tool 10.72.20.19:12001 display
输出示例:
# Item_Size Max_age 1MB_pages Count Full?
14 1.8 kB 28087 s 1 2 yes
各列的含义:
# slab class编号
Item_Size Chunk大小
Max_age LRU内最旧的记录的生存时间
1MB_pages 分配给Slab的页数
Count Slab内的记录数
Full? Slab内是否含有空闲chunk
#!/usr/bin/perl
#
# memcached-tool:
# stats/management tool for memcached.
#
# Author:Brad Fitzpatrick <brad@danga.com>
#
# Contributor:
# Andrey Niakhaichyk <andrey@niakhaichyk.org>
#
# License:
# public domain. I give up all rights to this
# tool. modify and copy at will.
#
use strict;
use IO::Socket::INET;
my $addr = shift;
my $mode = shift || "display";
my ($from, $to);
my $limit;
if ($mode eq "display") {
undef $mode if @ARGV;
} elsif ($mode eq "move") {
$from = shift;
$to = shift;
undef $mode if $from < 6 || $from > 17;
undef $mode if $to < 6 || $to > 17;
print STDERR "ERROR: parameters out of range\n\n" unless $mode;
} elsif ($mode eq 'dump') {
if (@ARGV) {
$limit = shift;
undef $mode if $limit < 1;
print STDERR "ERROR: invalid limit (should be a positive number)\n\n" unless $mode;
}
} elsif ($mode eq 'stats') {
;
} elsif ($mode eq 'settings') {
;
} elsif ($mode eq 'sizes') {
;
} else {
undef $mode;
}
undef $mode if @ARGV;
die "Usage: memcached-tool <host[:port] | /path/to/socket> [mode]\n
memcached-tool 10.0.0.5:11211 display # shows slabs
memcached-tool 10.0.0.5:11211 # same. (default is display)
memcached-tool 10.0.0.5:11211 stats # shows general stats
memcached-tool 10.0.0.5:11211 settings # shows settings stats
memcached-tool 10.0.0.5:11211 sizes # shows sizes stats
memcached-tool 10.0.0.5:11211 dump [limit] # dumps keys and values
WARNING! sizes is a development command.
As of 1.4 it is still the only command which will lock your memcached instance for some time.
If you have many millions of stored items, it can become unresponsive for several minutes.
Run this at your own risk. It is roadmapped to either make this feature optional
or at least speed it up.
" unless $addr && $mode;
sub server_connect {
my $sock;
if ($addr =~ m:/:) {
$sock = IO::Socket::UNIX->new( Peer => $addr, );
}
else {
$addr .= ':11211' unless $addr =~ /:\d+$/;
$sock = IO::Socket::INET->new(
PeerAddr => $addr,
Proto => 'tcp',
);
}
die "Couldn't connect to $addr\n" unless $sock;
return $sock;
}
my $sock = server_connect();
if ($mode eq 'dump') {
print STDERR "Dumping memcache contents";
print STDERR " (limiting to $limit keys)" unless !$limit;
print STDERR "\n";
print $sock "lru_crawler metadump all\r\n";
my %keyexp;
my $keycount = 0;
while (<$sock>) {
last if /^END/ or ($limit and $keycount == $limit);
# return format looks like this
# key=foo exp=2147483647 la=1521046038 cas=717111 fetch=no cls=13 size=1232
if (/^key=(\S+) exp=(-?\d+) .*/) {
my ($k, $exp) = ($1, $2);
$k =~ s/%(.{2})/chr hex $1/eg;
if ($exp == -1) {
$keyexp{$k} = 0;
} else {
$keyexp{$k} = $exp;
}
}
$keycount++;
}
if ($limit) {
# Need to reopen the connection here to stop the metadump in
# case the key limit was reached.
#
# XXX: Once a limit on # of keys returned is introduced in
# `lru_crawler metadump`, this should be removed and the proper
# parameter passed in the query above.
close($sock);
$sock = server_connect();
}
foreach my $k (keys(%keyexp)) {
print $sock "get $k\r\n";
my $response = <$sock>;
if ($response =~ /VALUE (\S+) (\d+) (\d+)/) {
my $flags = $2;
my $len = $3;
my $val;
read $sock, $val, $len;
print "add $k $flags $keyexp{$k} $len\r\n$val\r\n";
# get the END
$_ = <$sock>;
$_ = <$sock>;
}
}
exit;
}
if ($mode eq 'stats') {
my %items;
print $sock "stats\r\n";
while (<$sock>) {
last if /^END/;
chomp;
if (/^STAT\s+(\S*)\s+(.*)/) {
$items{$1} = $2;
}
}
printf ("#%-17s %5s %11s\n", $addr, "Field", "Value");
foreach my $name (sort(keys(%items))) {
printf ("%24s %12s\n", $name, $items{$name});
}
exit;
}
if ($mode eq 'settings') {
my %items;
print $sock "stats settings\r\n";
while (<$sock>) {
last if /^END/;
chomp;
if (/^STAT\s+(\S*)\s+(.*)/) {
$items{$1} = $2;
}
}
printf ("#%-17s %5s %11s\n", $addr, "Field", "Value");
foreach my $name (sort(keys(%items))) {
printf ("%24s %12s\n", $name, $items{$name});
}
exit;
}
if ($mode eq 'sizes') {
my %items;
print $sock "stats sizes\r\n";
while (<$sock>) {
last if /^END/;
chomp;
if (/^STAT\s+(\S*)\s+(.*)/) {
$items{$1} = $2;
}
}
printf ("#%-17s %5s %11s\n", $addr, "Size", "Count");
foreach my $name (sort(keys(%items))) {
printf ("%24s %12s\n", $name, $items{$name});
}
exit;
}
# display mode:
my %items; # class -> { number, age, chunk_size, chunks_per_page,
# total_pages, total_chunks, used_chunks,
# free_chunks, free_chunks_end }
print $sock "stats items\r\n";
my $max = 0;
while (<$sock>) {
last if /^END/;
if (/^STAT items:(\d+):(\w+) (\d+)/) {
$items{$1}{$2} = $3;
}
}
print $sock "stats slabs\r\n";
while (<$sock>) {
last if /^END/;
if (/^STAT (\d+):(\w+) (\d+)/) {
$items{$1}{$2} = $3;
$max = $1;
}
}
print " # Item_Size Max_age Pages Count Full? Evicted Evict_Time OOM\n";
foreach my $n (1..$max) {
my $it = $items{$n};
next if (0 == $it->{total_pages});
my $size = $it->{chunk_size} < 1024 ?
"$it->{chunk_size}B" :
sprintf("%.1fK", $it->{chunk_size} / 1024.0);
my $full = $it->{used_chunks} == $it->{total_chunks} ? "yes" : " no";
printf("%3d %8s %9ds %7d %7d %7s %8d %8d %4d\n",
$n, $size, $it->{age}, $it->{total_pages},
$it->{number}, $full, $it->{evicted},
$it->{evicted_time}, $it->{outofmemory});
}
1、memcached-tool可以方便地获得slab的使用情况。
2、使用方法也极其简单:perl memcached-tool server_ip:prot option。
3、有了这个工具就不需要自己写脚本,连接客户端,发送相应的信息,其实获取信息的方法就是给服务器端发送相应的指令。
stats 输出说明:
pid:memcache服务器的进程ID
uptime:服务器已经运行的秒数
time:服务器当前的unix时间戳
version:memcache 版本
pointer_size:当前操作系统的指针大小(32位系统一般是32bit)
rusage_user:进 程的累计用户时间
rusage_system:进程的累计系统时间
curr_items:服务器当前存储的items数量
total_items:从服务器启动以后存储的items总数量
bytes:当前服务器存储items占用的字节数
curr_connections:当前打开着的连接数
total_connections:从服务器启动以后曾经打开过的连接数
connection_structures:服务器分配的连接 构造数
cmd_get:get命令(获取)总请求次数
cmd_set:set 命令(保存)总请求次数
get_hits:总命中次数
get_misses:总未命中次数
evictions:为获取空闲内存而删除的items数(分配给memcache的空间用满后需要删除旧的items来得到空间分配给新的items)
bytes_read:总读取字 节数(请求字节数)
bytes_written:总发送字节数(结果字节数)
limit_maxbytes:分配给memcache的内存大小(字节)
threads:当前线程数
工具主页:github_scripts_memcached-tool