获取所有memcached键的最简单方法是什么,并将其转储到文件中?

18

这些内容是关于一个只有一个Memcached服务器的,大约有20M个键(没有到期时间)和大约2G数据的描述。

获取所有键/值对到一个平面文件中的最简单方法是什么?我首先查看了java net.spy.memcached.MemcachedClient,但是这个客户端不支持获取所有键(我想)。如果我有所有键的列表(我没有),我可以轻松地使用此客户端获取所有值。

我知道可以使用一些telnet命令(例如,telnet localhost 11211; stats items; stats cachedump)获取所有键,但我不清楚如何使其自动化并且稳健。

编辑:这是我在我的机器上的玩具memcached服务器上使其运行的方法。它似乎有效,但我只将两个键放入了memcached中,因此希望这种方法可以很好地扩展:

shell命令:

sudo yum install memcached
sudo /etc/init.d/memcached restart # maybe unnecessary
sudo yum install php
sudo yum install php-pecl-memcache
sudo service httpd reload

基于这个的php脚本:

<?php
$memcache = new Memcache();
$memcache->connect('127.0.0.1', 11211) or die ("Could not connect");
$list = array();
$allSlabs = $memcache->getExtendedStats('slabs');
$items = $memcache->getExtendedStats('items');
foreach($allSlabs as $server => $slabs) {
    foreach($slabs AS $slabId => $slabMeta) {
        if (!is_int($slabId)) {
            continue;
        }
        $cdump = $memcache->getExtendedStats('cachedump', (int) $slabId, 100000000);
        foreach($cdump AS $server => $entries) {
            if ($entries) {
                foreach($entries AS $eName => $eData) {
                    print_r($eName);
                    print_r(":");
                    $val = $memcache->get($eName);
                    print_r($val);
                    print_r("\n");
                }
            }
        }
    }
}
?>

编辑2: 上述脚本似乎不能返回所有映射关系。如果我插入行count($entries),即使将限制参数设置为100M,它也仅返回略多于50k条数据,但是通过telnet执行stats items则显示有超过5M的记录。有人知道这可能是什么原因吗?

编辑3: 这个链接表明,缓存转储并不能从memcached中获取所有键。我已经遇到了大约50k个键的限制,无论是通过cachedump,这个PHP脚本还是类似Zach Bonham提供的链接中的perl脚本返回的。有没有什么方法可以解决这个问题?


发现了这个链接,可能会有所帮助:http://blog.evanweaver.com/2009/04/20/peeping-into-memcached/ - Brad
可能是获取Memcached中设置的所有键的重复问题。 - kenorb
5个回答

14

免责声明:我不知道我在做什么,只是听起来像一个有趣的问题。

你看过这篇文章吗?Lars Windolf写的“如何从Memcache中转储密钥”

从文章中可以了解到:

Memcache本身提供了查看数据的手段。协议提供了查看由slabs(给定大小范围内的数据类别)组织的数据的命令。但是有一些重要限制:

  • 您只能按slab类别(具有大致相同内容大小的键)转储密钥
  • 每个slab类别只能转储一页(1MB的数据)
  • 这是一项非官方功能,随时可能被删除。

实际上,需要了解Memcache如何将数据存储在内存中(这一点我不清楚)。您需要找到每个'slab',然后可以转储该slab的密钥,最终转储这些密钥的值。

文章中的工具部分使用各种语言转储至少密钥,但是只有perl脚本转储了键和值。


5
链接无效。这是一个好的链接: https://lzone.de/blog/How-to%20Dump%20Keys%20from%20Memcache - mcoolive
似乎只有在使用“基于文本的”Memcached协议时才有效。当使用二进制协议(和SASL)时,我找不到一种方法来执行stats cachedump 1 100(似乎binary protocol规范不支持在cachedump之后向stats传递参数)。 - Dimitry K

9

memccat

这里是我用来将所有对象转储到相应文件中的脚本:

while read -r key; do
    [ -f "$key" ] || echo "get $key" | nc localhost 11211 > "$key.dump";
done < <(memcdump --server localhost)

它使用应该是memcached工具的一部分的memcdump命令。

对于压缩对象,请参见:如何从Memcache中转储给定键的压缩对象?

memcdump

要从服务器转储密钥列表,请使用memcdump/memdump工具,例如:

memcdump --servers=localhost | tee my_keys.lst

使用 netcat 打印单个项目的值:
echo "get 13456_-cache-some_object" | nc localhost 11211

通过memcdump/memdumpnetcat将所有对象转储到屏幕上:

memcdump --servers=localhost | xargs -L1 -I% sh -c 'echo "get %" | nc localhost 11211'

memcached-tool

在最新版本的memcached中,也有memcached-tool命令,例如:

memcached-tool localhost:11211 dump | less # dumps keys and values

4

目前,对于slab的转储大小有一个固定的限制,即2MB。除非您重新编写do_item_cachedump代码,否则无法获取所有键。


3
我使用了这个 Bash 脚本。
#!/bin/sh
MESSAGE=`memdump --servers="127.0.0.1"`
while read -r line; do
    echo $line
    VALUE=`echo "get $line" | nc 127.0.0.1 11211`
    echo $VALUE
done <<< "$MESSAGE"

如果需要,请更改IP /端口。


3
你的发行版中,二进制文件可能被命名为 memcdump 而不是 memdump - Ross Rogers
memdump:无效选项--'-'。 - DimiDak
@RossRogers 是的,在 Debian 中使用 memcdump。安装方法:apt install libmemcached-tools - DimiDak

1

Bash

使用Bash并将其保存到文件中:

exec {memcache}<>/dev/tcp/localhost/11211
printf "stats items\nquit\n" >&${memcache}
cat <&${memcache} > myfile.txt

相关链接:在纯Bash中编写Redis客户端(这是关于Redis的,但方法非常类似)


这只转储统计数据,但也很有用。 - PetrV

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接