Java 使用 MemCachedClient 遍历 Memcached 所有 Key 的方法
在 Java Memcached Client 的官方文档中,并没有直接提供遍历 Memcached 中所有 Key 的方法。不过,我们可以通过 statsItems 和 statsCacheDump 这两个底层命令来实现。statsItems 能告诉我们有多少个 Item 以及每个 Item 包含多少个 Key,而 statsCacheDump 则能获取具体到每个 Key 的详细信息(名称、大小、有效期)。
关于数据类型的疑问
很多开发者会问:Memcached 存储的是键值对,如果 A 客户端存了一个 String 类型和一个 Object 类型的 Key,B 客户端怎么知道哪个是 String 哪个是 Object?
其实,Memcached 服务端本身并不区分数据类型,它只存储字节流。所谓的类型信息完全依赖于客户端序列化框架的处理。当你调用 set 方法时,无论传入什么对象,最终都是序列化为字节存入缓存的。因此,无法直接从缓存端区分原始数据类型,这需要在业务层通过约定或元数据管理来解决。
核心实现逻辑
下面是一个基于 keysBean 的工具类示例。这个 Bean 定义了三个属性来存储服务器地址、数据大小和过期时间。
public class KeysBean {
private String server;
private long bytes;
private long expiry;
// 构造函数、Getter/Setter 省略
}
具体的遍历方法如下。这里需要注意,mcc 实例需要预先初始化好连接。代码中主要涉及两个步骤:先通过 statsItems 拿到 Item 数量,再根据 Item ID 调用 statsCacheDump 拉取具体 Key 列表。
public static Map<String, KeysBean> getKeysForMap() throws UnsupportedEncodingException {
Map<String, KeysBean> keylist = new HashMap<>();
// 1. 获取统计信息,结构类似 items:2:number=14
Map<String, Map<String, String>> statsItems = mcc.statsItems();
for (String server : statsItems.keySet()) {
Map<String, String> statsItems_sub = statsItems.get(server);
int items_number = 0;
// 2. 解析出当前服务器的 Item 数量
for (String key : statsItems_sub.keySet()) {
(key.toUpperCase().startsWith() && key.toUpperCase().endsWith()) {
items_number = Integer.parseInt(statsItems_sub.get(key).trim());
;
}
}
(items_number > ) {
Map<String, Map<String, String>> statsCacheDump = mcc.statsCacheDump( []{server}, , items_number);
(Map.Entry<String, Map<String, String>> entry : statsCacheDump.entrySet()) {
Map<String, String> dump_sub = entry.getValue();
(Map.Entry<String, String> kEntry : dump_sub.entrySet()) {
kEntry.getKey();
kEntry.getValue();
{
valueInfo.indexOf();
valueInfo.indexOf();
Long.parseLong(valueInfo.substring(bIndex + , sIndex).trim());
Long.parseLong(valueInfo.substring(sIndex + ).trim());
URLDecoder.decode(rawKey, );
keylist.put(decodedKey, (server, size, expire));
} (Exception e) {
}
}
}
}
}
keylist;
}

