在我的Redis DB中,我有一些前缀:<numeric_id>哈希值。

有时我想把它们都原子地清除掉。如何在不使用分布式锁定机制的情况下做到这一点呢?


当前回答

如果你的键名中有空格,这将适用于MacOS

redis-cli --scan --pattern "myprefix:*" | tr \\n \\0 | xargs -0 redis-cli unlink

其他回答

这个对我有用,但可能不是原子:

redis-cli keys "stats.*" | cut -d ' ' -f2 | xargs -d '\n' redis-cli DEL

我支持所有与有一些工具或执行Lua表达式相关的答案。

我还有一个选择:

在我们的生产和预生产数据库中,有数千个键。时不时地,我们需要删除一些键(通过一些掩码),修改一些标准等。当然,没有办法从CLI手动完成,特别是使用分片(每个物理分区中有512个逻辑dbs)。

为此,我编写了一个java客户端工具来完成所有这些工作。在删除键的情况下,实用程序可以非常简单,只有一个类:

public class DataCleaner {

    public static void main(String args[]) {
        String keyPattern = args[0];
        String host = args[1];
        int port = Integer.valueOf(args[2]);
        int dbIndex = Integer.valueOf(args[3]);

        Jedis jedis = new Jedis(host, port);

        int deletedKeysNumber = 0;
        if(dbIndex >= 0){
            deletedKeysNumber += deleteDataFromDB(jedis, keyPattern, dbIndex);
        } else {
            int dbSize = Integer.valueOf(jedis.configGet("databases").get(1));
            for(int i = 0; i < dbSize; i++){
                deletedKeysNumber += deleteDataFromDB(jedis, keyPattern, i);
            }
        }

        if(deletedKeysNumber == 0) {
            System.out.println("There is no keys with key pattern: " + keyPattern + " was found in database with host: " + host);
        }
    }

    private static int deleteDataFromDB(Jedis jedis, String keyPattern, int dbIndex) {
        jedis.select(dbIndex);
        Set<String> keys = jedis.keys(keyPattern);
        for(String key : keys){
            jedis.del(key);
            System.out.println("The key: " + key + " has been deleted from database index: " + dbIndex);
        }

        return keys.size();
    }

}

请使用此命令并尝试:

redis-cli --raw keys "$PATTERN" | xargs redis-cli del

从redis 2.6.0开始,你可以运行lua脚本,它以原子方式执行。我从来没有写过,但我想应该是这样的

EVAL "return redis.call('del', unpack(redis.call('keys', ARGV[1])))" 0 prefix:[YOUR_PREFIX e.g delete_me_*]

警告:正如Redis文档所说,由于性能问题,关键字 命令不应用于生产中的常规操作,此 命令用于调试和特殊操作。读 更多的

请参阅EVAL文档。

我也遇到了同样的问题。我为用户存储会话数据的格式为:

session:sessionid:key-x - value of x
session:sessionid:key-y - value of y
session:sessionid:key-z - value of z

因此,每个条目都是一个单独的键值对。当会话被销毁时,我想通过使用模式session:sessionid:* -删除键来删除所有会话数据,但redis没有这样的功能。

我所做的是:将会话数据存储在散列中。我只是用session:sessionid的哈希id创建了一个哈希,然后我在那个哈希中推key-x, key-y, key-z(顺序对我来说并不重要),如果我不再需要那个哈希,我只是做一个DEL session:sessionid,所有与那个哈希id相关的数据都消失了。DEL是原子的,访问数据/向哈希写入数据是O(1)。