Java中memcached 如何获取所有未过期的key?

Java中memcached 如何获取所有未过期的key?下面写了一个获取所有key的方法,但是会得到过期的key,如何过滤掉?

public static List<String> getAllKey(String reg) {
        List<String> keylist = new ArrayList<String>();
        Map<String, Map<String, String>> statsItems = memcachedClient.statsItems(); //获取所有items
        Map<String, String> statsItems_sub = null;
        String server = null;
        String statsItems_sub_key = null;
        int items_number = 0;

        Map<String, Map<String, String>> statsCacheDump = null;
        Map<String, String> statsCacheDump_sub = null;
        String statsCacheDumpsub_key = null;
        for (Iterator<String> iterator = statsItems.keySet().iterator(); iterator.hasNext(); ) {
            server = iterator.next(); //server地址
            keylist.add(server);
            statsItems_sub = statsItems.get(server);
            for (Iterator<String> iterator_item = statsItems_sub.keySet().iterator(); iterator_item.hasNext(); ) {
                statsItems_sub_key = iterator_item.next();
                if (statsItems_sub_key.toUpperCase().startsWith("items:".toUpperCase()) && statsItems_sub_key.toUpperCase().endsWith(":number".toUpperCase())) {
                    items_number = Integer.parseInt(statsItems_sub.get(statsItems_sub_key).trim());
                    statsCacheDump = memcachedClient.statsCacheDump(new String[]{server}, Integer.parseInt(statsItems_sub_key.split(":")[1].trim()), items_number); //获取一个item
                    for (Iterator<String> statsCacheDump_iterator = statsCacheDump.keySet().iterator(); statsCacheDump_iterator.hasNext(); ) {
                        statsCacheDump_sub = statsCacheDump.get(statsCacheDump_iterator.next());
                        for (Iterator<String> iterator_keys = statsCacheDump_sub.keySet().iterator(); iterator_keys.hasNext(); ) {
                            statsCacheDumpsub_key = (String) iterator_keys.next(); //获取item的key
                            if(statsCacheDumpsub_key.contains(reg)){
                                keylist.add(statsCacheDumpsub_key);
                            }
                        }
                    }
                }
            }
        }
        return keylist;
    }
阅读 625
avatarAI BotBETA

首先,需要理解statsCacheDump方法返回的是服务器上所有缓存的详细信息,包括键、大小、最后修改时间、到期时间等。这些信息被组织成不同的块,每个块包含一组缓存项。每个缓存项都包含一个键、一个值以及与之相关的元数据。

在你的代码中,你正在遍历每个缓存项的键,并检查它们是否包含你提供的正则表达式。但是,这并没有过滤掉过期的键,因为过期的键和不过期的键在缓存项的元数据中都有相同的键。

为了过滤掉过期的键,你需要查看每个缓存项的到期时间。在Memcached中,每个缓存项都有一个与之相关的到期时间,这个时间表示该缓存项在多少秒后过期。你可以查看这个到期时间,并过滤掉那些已经过期的缓存项。

不幸的是,Java的Memcached客户端库并不直接提供获取所有未过期键的方法。你需要自己编写代码来遍历所有缓存项,并检查它们的到期时间。以下是一个可能的解决方案:

public static List<String> getAllNonExpiredKeys(String reg) {
    List<String> keylist = new ArrayList<String>();
    Map<String, Map<String, String>> statsItems = memcachedClient.statsItems(); //获取所有items
    Map<String, String> statsItems_sub = null;
    String server = null;
    String statsItems_sub_key = null;
    int items_number = 0;

    Map<String, Map<String, String>> statsCacheDump = null;
    Map<String, String> statsCacheDump_sub = null;
    String statsCacheDumpsub_key = null;
    for (Iterator<String> iterator = statsItems.keySet().iterator(); iterator.hasNext(); ) {
        server = iterator.next(); //server地址
        keylist.add(server);
        statsItems_sub = statsItems.get(server);
        for (Iterator<String> iterator_item = statsItems_sub.keySet().iterator(); iterator_item.hasNext(); ) {
            statsItems_sub_key = iterator_item.next();
            if (statsItems_sub_key.toUpperCase().startsWith("items:".toUpperCase()) && statsItems_sub_key.toUpperCase().endsWith(":number".toUpperCase())) {
                items_number = Integer.parseInt(statsItems_sub.get(statsItems_sub_key).trim());
                statsCacheDump = memcachedClient.statsCacheDump(new String[]{server}, Integer.parseInt(statsItems_sub_key.split(":")[1].trim()), items_number); //获取一个item
                for (Iterator<String> statsCacheDump_iterator = statsCacheDump.keySet().iterator(); statsCacheDump_iterator.hasNext(); ) {
                    statsCacheDump_sub = statsCacheDump.get(statsCacheDump_iterator.next());
                    for (Iterator<String> iterator_keys = statsCacheDump_sub.keySet().iterator(); iterator_keys.hasNext(); ) {
                        statsCacheDumpsub_key = (String) iterator_keys.next(); //获取item的key
                        if(statsCacheDumpsub_key.contains(reg) && !isExpired(statsCacheDumpsub_key, statsCacheDump_sub)){
                            keylist.add(statsCacheDumpsub_key);
                        }
                    }
                }
            }
        }
    }
    return keylist;
}

private static boolean isExpired(String key, Map<String, String> item) {
    // 获取过期时间字符串,例如 "exptime:1647434807"
    String expTimeStr = item.get("exptime"); 
    if (expTimeStr != null) {
        long expTime = Long.parseLong(expTimeStr.split(":")[1]); // 解析过期时间(秒)
        return System.currentTimeMillis() / 1000 > expTime; // 检查是否过期(当前时间大于过期时间)
    } else {
        return false; // 如果未设置过期时间,则认为未过期
    }
}

在这个代码中,我增加了一个名为isExpired的方法来检查每个缓存项是否已经过期。这个方法首先获取缓存项的过期时间字符串,然后解析这个字符串以获取过期时间(以秒为单位)。然后,它检查当前时间是否大于过期时间,如果是,则认为该缓存项已经过期。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题