Redis / Jedis – 按模式删除?
通常,我得到密钥集然后使用外观删除每个键/值对。
是否可以通过模式删除所有键?
即:
Del sample_pattern:*
看来,对于Jedis来说,“按模式删除”基本上是获取特定模式的所有键然后循环通过它。
即
Set keys = jedis.keys(pattern); for (String key : keys) { jedis.del(key); }
不建议使用KEYS,因为它在生产中使用效率低下。 请参阅https://redis.io/commands/keys 。 相反,最好使用SCAN。 另外,比重复调用jedis.del()更有效的调用是对jedis进行一次调用以删除匹配的键,传入要删除的键数组。 下面介绍一种更有效的解决方案:
Set matchingKeys = new HashSet<>(); ScanParams params = new ScanParams(); params.match("sample_pattern:*"); try(Jedis jedis = jedisPoolFactory.getPool().getResource()) { String nextCursor = "0"; do { ScanResult scanResult = jedis.scan(nextCursor, params); List keys = scanResult.getResult(); nextCursor = scanResult.getStringCursor(); matchingKeys.addAll(keys); } while(!nextCursor.equals("0")); if (matchingKeys.size() == 0) { return; } jedis.del(matchingKeys.toArray(new String[matchingKeys.size()])); }
你应该尝试使用eval 。 我不是Lua专家,但这段代码有效。
private static final String DELETE_SCRIPT_IN_LUA = "local keys = redis.call('keys', '%s')" + " for i,k in ipairs(keys) do" + " local res = redis.call('del', k)" + " end"; public void deleteKeys(String pattern) { Jedis jedis = null; try { jedis = jedisPool.getResource(); if (jedis == null) { throw new Exception("Unable to get jedis resource!"); } jedis.eval(String.format(DELETE_SCRIPT_IN_LUA, pattern)); } catch (Exception exc) { if (exc instance of JedisConnectionException && jedis != null) { jedisPool.returnBrokenResource(jedis); jedis = null; } throw new RuntimeException("Unable to delete that pattern!"); } finally { if (jedis != null) { jedisPool.returnResource(jedis); } } }
然后打电话:
deleteKeys("temp:keys:*");
这保证了一个服务器端调用,多个删除操作。
您可以在一行中使用Redisson :
redisson.getKeys().deleteByPattern(pattern)
你可以用bash做到这一点:
$ redis-cli KEYS "sample_pattern:*" | xargs redis-cli DEL
使用java删除,它看起来像这样:
String keyPattern = "sample_pattern:*"; Set keys = jedis.keys(keyPattern); for(String key:keys){ jedis.del(key); }