在 memcached 中设置所有密钥

如何在 memcached 实例中设置所有键?

我试过在谷歌上搜索,但没有找到什么,除了 PHP支持 getAllKeys方法,这意味着它实际上是可以做到这一点的。如何在 telnet 会话中获得相同的结果?

我已经尝试了 Memcached 备忘单Memcached telnet 命令摘要中提到的所有检索相关选项,但它们都不起作用,我不知道如何找到正确的方法来做到这一点。

注意: 我目前正在开发中这样做,因此可以假定,将不会有任何问题,由于新的键被设置或其他这样的竞争条件发生,并且键的数量也将受到限制。

216551 次浏览

找到了一个方法,感谢 这里有链接(与原来的 谷歌小组讨论)

首先,向服务器发送 Telnet:

telnet 127.0.0.1 11211

接下来,列出获取板 ID 的项目:

stats items
STAT items:3:number 1
STAT items:3:age 498
STAT items:22:number 1
STAT items:22:age 498
END

“ item”之后的第一个数字是 slabid。请求每个平板 ID 的缓存转储,并限制要转储的最大密钥数量:

stats cachedump 3 100
ITEM views.decorators.cache.cache_header..cc7d9 [6 b; 1256056128 s]
END


stats cachedump 22 100
ITEM views.decorators.cache.cache_page..8427e [7736 b; 1256056128 s]
END


memdump

有一个 memcdump(有时是 memdump)命令(libmemcached-tools的一部分) ,例如:

memcdump --servers=localhost

它会返回所有的钥匙。


memcached-tool

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

memcached-tool localhost:11211 dump | less

它转储所有键和值。

参见:

基于这里的 @ mu 無答案。我已经写了一个缓存转储脚本。

该脚本转储 memcached 服务器的所有内容。它使用 Ubuntu 12.04和一个 localhost memcached 进行了测试,因此您的收益可能会有所不同。

#!/usr/bin/env bash


echo 'stats items'  \
| nc localhost 11211  \
| grep -oe ':[0-9]*:'  \
| grep -oe '[0-9]*'  \
| sort  \
| uniq  \
| xargs -L1 -I{} bash -c 'echo "stats cachedump {} 1000" | nc localhost 11211'

它所做的就是遍历所有缓存板,并打印每个缓存板的1000个条目。

请注意此脚本的某些限制,例如,它可能不适用于5GB 的缓存服务器。但是它对于在本地机器上进行调试非常有用。

最简单的方法是使用 python-memcached-stats 包 https://github.com/abstatic/python-memcached-stats

Key ()方法应该可以让您继续下去。

例子-

from memcached_stats import MemcachedStats
mem = MemcachedStats()


mem.keys()
['key-1',
'key-2',
'key-3',
... ]

如果安装了 PHP 和 PHP-memcached,则可以运行

$ php -r '$c = new Memcached(); $c->addServer("localhost", 11211); var_dump( $c->getAllKeys() );'

巴斯

要获取 Bash 中的键列表,请按照以下步骤操作。

首先,定义以下包装函式,使其易于使用(复制并粘贴到 shell 中) :

function memcmd() {
exec {memcache}<>/dev/tcp/localhost/11211
printf "%s\n%s\n" "$*" quit >&${memcache}
cat <&${memcache}
}

Memcached 1.4.31及以上版本

可以使用 lru_crawler metadump all命令为缓存中的(所有)项转储(大部分)元数据。

cachedump不同,它不会导致严重的性能问题,并且对可以转储的键的数量没有限制。

使用前面定义的函数执行示例命令:

memcmd lru_crawler metadump all

见: 释放通知1431


Memcached 1.4.30及以下版本

使用 项目统计命令获取板的列表,例如:

memcmd stats items

对于每个 slub 类,您可以通过指定 slub id 和限制编号(0-无限制)来获得项目列表:

memcmd stats cachedump 1 0
memcmd stats cachedump 2 0
memcmd stats cachedump 3 0
memcmd stats cachedump 4 0
...

注意: 您需要对每个 memcached 服务器执行此操作。

要列出所有存根中的所有密钥,以下是一行程序(每个服务器) :

for id in $(memcmd stats items | grep -o ":[0-9]\+:" | tr -d : | sort -nu); do
memcmd stats cachedump $id 0
done

注意: 上面的命令在访问这些项时可能会导致严重的性能问题,因此建议不要在活动状态下运行。


备注:

stats cachedump只转储 HOT_LRU(IIRC?),在活动发生时由后台线程管理。这意味着在一个新的足够的版本下,2Q 算法启用,你会得到什么是在只有一个 LRU 的快照视图。

如果您想查看所有内容,那么 lru_crawler metadump 1(或 lru_crawler metadump all)是一种新的大多受官方支持的方法,它将异步转储您想要的任意数量的键。你会得到他们的秩序,但它打所有 LRU 的,除非你删除/替换项目多次运行应该产生相同的结果。

资料来源: GH-405


相关阅读:

我使用的是 Java 的 spyMemcached,并使用了这段代码

@Autowired
@Qualifier("initMemcachedClient")
private MemcachedClient memcachedClient;


public List<String> getCachedKeys(){
Set<Integer> slabIds = new HashSet<>();
Map<SocketAddress, Map<String, String>> stats;
List<String> keyNames = new ArrayList<>();


// Gets all the slab IDs
stats = memcachedClient.getStats("items");
stats.forEach((socketAddress, value) -> {
System.out.println("Socket address: "+socketAddress.toString());
value.forEach((propertyName, propertyValue) -> {
slabIds.add(Integer.parseInt(propertyName.split(":")[1]));
});
});


// Gets all keys in each slab ID and adds in List keyNames
slabIds.forEach(slabId -> {
Map<SocketAddress, Map<String, String>> keyStats = memcachedClient.getStats("cachedump "+slabId+" 0");
keyStats.forEach((socketAddress, value) -> {
value.forEach((propertyName, propertyValue) -> {
keyNames.add(propertyName);
});
});
});


System.out.println("number of keys: "+keyNames.size());
return keyNames;
}

Java 解决方案:

谢谢!@Satvik Nema 您的解决方案帮助我找到了这种方法,但是它不适用于 memcached 2.4.6版本 不确定什么时候包括了新的方法 getStatsByItem。 我使用文档计算出了需要的更改,下面的代码对我很有用。

// Gets all the slab IDs
Set<Integer> slabIds = new HashSet<>();
Map<InetSocketAddress, Map<String, String>> itemsMap = null;
try {
itemsMap = this.memcachedClient.getStatsByItem("items");
} catch (Exception e) {
log.error("Failed while pulling 'items'. ERROR", e);
}
    

if (Objects.nonNull(itemsMap)) {
itemsMap.forEach((key, value) -> {
log.info("itemsMap {} : {}", key, value);
value.forEach((k, v) -> {
slabIds.add(Integer.parseInt(k.split(":")[1]));
});
});
}
    

// Gets all keys in each slab ID and adds in List keyNames
slabIds.forEach(slabId -> {
Map<InetSocketAddress, Map<String, String>> keyStats = null;
try {
keyStats = this.memcachedClient.getStatsByItem("cachedump " + slabId + " 0");
} catch (Exception e) {
log.error("Failed while pulling 'cachedump' for slabId: {}. ERROR", slabId, e);
}
if (Objects.nonNull(keyStats)) {
keyStats.forEach((socketAddress, value) -> {
value.forEach((propertyName, propertyValue) -> {
//keyNames.add(propertyName);
log.info("keyName: {} Value: {}", propertyName, propertyValue);
});
});
}
});