Redis/Jedis - Delete by pattern?

前端 未结 5 611
渐次进展
渐次进展 2021-02-04 11:38

Normally, I get the key set then use a look to delete each key/value pair.

Is it possible to just delete all keys via pattern?

ie:

Del sample_pat         


        
相关标签:
5条回答
  • 2021-02-04 12:04

    You can do it with the Redisson in one line:

    redisson.getKeys().deleteByPattern(pattern)
    
    0 讨论(0)
  • 2021-02-04 12:11

    You can do it with bash:

    $ redis-cli KEYS "sample_pattern:*" | xargs redis-cli DEL
    
    0 讨论(0)
  • 2021-02-04 12:13

    It seems, for Jedis, to "delete by pattern" is basically getting all the keys of a specific pattern then loop through it.

    ie

    Set<String> keys = jedis.keys(pattern);
    for (String key : keys) {
        jedis.del(key);
    } 
    
    0 讨论(0)
  • 2021-02-04 12:14

    You should try using eval. I'm no Lua expert, but this code works.

    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);
        }
      }
    }
    

    And then call:

    deleteKeys("temp:keys:*");
    

    This guarantees a one server-side call, multiple delete operation.

    0 讨论(0)
  • 2021-02-04 12:17

    KEYS is not recommended to use due to its inefficiencies when used in production. Please see https://redis.io/commands/keys. Instead, it is better to use SCAN. Additionally, a more efficient call than repeated calls to jedis.del() is to make one single call to jedis to remove the matching keys, passing in an array of keys to delete. A more efficient solution is presented below:

    Set<String> matchingKeys = new HashSet<>();
    ScanParams params = new ScanParams();
    params.match("sample_pattern:*");
    
    try(Jedis jedis = jedisPoolFactory.getPool().getResource()) {
        String nextCursor = "0";
    
        do {
            ScanResult<String> scanResult = jedis.scan(nextCursor, params);
            List<String> 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()]));
    }
    
    0 讨论(0)
提交回复
热议问题