将所有 memcached 密钥转储到文件中的最简单方法是啥?
Posted
技术标签:
【中文标题】将所有 memcached 密钥转储到文件中的最简单方法是啥?【英文标题】:What's the simplest way to get a dump of all memcached keys into a file?将所有 memcached 密钥转储到文件中的最简单方法是什么? 【发布时间】:2012-12-06 02:21:08 【问题描述】:这仅来自单个 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 脚本,基于this:
<?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)
行,即使将limit 参数设置为100M,它也只会返回50k 多一点,但是从telnet 执行stats items
会显示超过5M 的条目。有谁知道为什么会这样?
EDIT3:link 表明 cachedump 不会从 memcached 中获取所有键。我已经达到了大约 50k 键的限制,这些键由 cachedump、此 PHP 脚本或类似于 Zach Bonham 提供的链接中的一个 perl 脚本返回。有没有办法解决这个问题?
【问题讨论】:
找到这个,这可能会有所帮助:blog.evanweaver.com/2009/04/20/peeping-into-memcached get all keys set in memcached的可能重复 【参考方案1】:免责声明:我不知道自己在做什么,只是听起来像是一个有趣的问题。
你看到这篇文章了吗? "How to Dump Keys from Memcache" 拉尔斯·温多夫。
来自文章:
Memcache 本身提供了进入数据峰值的方法。协议 提供命令以使数据达到峰值,这些数据由平板组织 (给定大小范围的数据类别。有一些重要的 限制:
您只能转储每个平板类的密钥(内容大小大致相同的密钥) 每个slab 类只能转储一个页面(1MB 数据) 这是一项非官方功能,可能随时会被删除。
实际上,它需要一些关于 memcache 如何在内存中存储数据的知识(我不知道)。您需要找到每个“slab”,然后您可以转储该slab 的键,然后最终转储这些键的值。
文章中有一个工具部分,它使用各种语言至少转储键,但只有 perl 脚本转储键和值。
【讨论】:
网址已损坏。这是一个很好的lzone.de/blog/How-to%20Dump%20Keys%20from%20Memcache 这似乎只在使用“基于文本”的 memcached 协议时才有效。使用二进制协议(和 SASL)时,我找不到执行stats cachedump 1 100
的方法(好像binary protocol 规范不支持在cachedump
之后将参数传递给stats
)【参考方案2】:
memccat
这是我用来将所有对象转储到相应文件中的脚本:
while read -r key; do
[ -f "$key" ] || echo "get $key" | nc localhost 11211 > "$key.dump";
done < <(memcdump --server localhost)
它使用memcdump
命令,该命令应该是memcached utils 的一部分。
压缩对象见:How to dump a compressed object for given key from 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
中还有memcached-tool
命令,例如
memcached-tool localhost:11211 dump | less # dumps keys and values
【讨论】:
【参考方案3】:slab 转储的硬编码限制为 2MB。除非您重写 do_item_cachedump,否则您将无法取出所有密钥。
【讨论】:
【参考方案4】:我使用了这个 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 / 端口
【讨论】:
二进制文件在您的发行版中可能被命名为memcdump
而不是 memdump
。
memdump: 无效选项 -- '-'
@RossRogers 是的,memcdump
在 debian 中。安装:apt install libmemcached-tools
【参考方案5】:
重击
使用 Bash 并保存到文件中:
exec memcache<>/dev/tcp/localhost/11211
printf "stats items\nquit\n" >&$memcache
cat <&$memcache > myfile.txt
相关:Writing a Redis client in pure bash(它是 Redis,但方法非常相似)
【讨论】:
这只会转储统计信息,但也很有用以上是关于将所有 memcached 密钥转储到文件中的最简单方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章