16

这仅来自具有大约 20M 键(没有过期)和大约 2G 数据的单个 memcached 服务器。

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

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

编辑:这是我在我的机器上的玩具 memcached 服务器上所做的工作。它似乎有效,但我只在 memcached 中放了两个键,所以希望这种方法可以正常扩展:

外壳命令:

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");
                }
            }
        }
    }
}
?>

EDIT2:上面的脚本似乎没有返回所有的映射。如果我插入该行count($entries),即使将限制参数设置为 100M,它也只返回 50k 多一点,但从stats itemstelnet 执行显示超过 5M 条目。有谁知道为什么会这样?

EDIT3:此链接表明 cachedump 不会从 memcached 获取所有密钥。我已经达到了大约 50k 键的限制,这些键由 cachedump、此 PHP 脚本或类似于 Zach Bonham 提供的链接中的一个 perl 脚本返回。有没有办法解决?

4

5 回答 5

14

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

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

来自文章:

Memcache 本身提供了进入数据峰值的方法。该协议提供了命令以使按平板组织的数据达到峰值(给定大小范围的数据类别。但存在一些重大限制:

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

实际上,它需要一些关于 memcache 如何在内存中存储数据的知识(我没有)。您需要找到每个“板”,然后您可以转储该板的键,然后最终转储这些键的值。

文章中有一个工具部分,它使用各种语言至少转储键,但只有 perl 脚本转储键和值。

于 2012-12-18T21:21:44.967 回答
8

关注

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

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

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

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

内存转储

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

memcdump --servers=localhost | tee my_keys.lst

要打印一项的值,请使用netcat

echo "get 13456_-cache-some_object" | nc localhost 11211

通过memcdump/memdump和将所有对象转储到屏幕中netcat

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

内存缓存工具

在最新版本中memcached还有memcached-tool命令,例如

memcached-tool localhost:11211 dump | less # dumps keys and values
于 2015-03-09T18:01:21.750 回答
3

平板转储的硬编码限制为 2MB。除非您重写 do_item_cachedump,否则您将无法取出所有密钥。

于 2013-10-14T07:29:08.517 回答
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 / 端口

于 2015-01-23T13:59:07.680 回答
1

重击

使用 Bash 并保存到文件中:

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

相关:用纯 bash 编写 Redis 客户端(它是 Redis,但方法非常相似)

于 2018-10-25T09:24:41.300 回答