StackExchange Redis删除所有以开头的键
StackExchange Redis delete all keys that start with
我有一个格式的密钥:
Error.1
Error.24
Error.32
使用 StackExchange.Redis
,我将如何处理所有匹配格式 Error.
的键的 KeyDelete
?
在另一个答案中,我看到了 LUA 脚本:
EVAL "return redis.call('del', unpack(redis.call('keys', ARGV[1])))" 0 Error.*
但我不确定如何使用 Database.ScriptEvaluate()
来调用它
只需获取所有与模式匹配的键,迭代并删除,就像这样:
using (var redisConnection = ConnectionMultiplexer.Connect(...))
{
var server = redisConnection.GetServer(endpoint:...);
if (server != null)
{
foreach (var key in server.Keys(pattern: "Error.*"))
{
redisConnection.Database.KeyDelete(key);
}
}
}
稍后编辑:
设置Redis连接的例子:https://gist.github.com/cristipufu/9ad47caf3dba60d712484d0c880597b9
应该存储和重复使用多路复用器,而不是每次都丢弃和重新创建。 https://stackexchange.github.io/StackExchange.Redis/Basics
通过调整/指定 Keys 调用的 pageSize 参数可以显着提高性能。它的默认值为 10。尝试 1,000。
StackExchange.Redis server.Keys(pattern:"IsVerySlow*")
并且 通过 IAsyncEnumerable
使用 C# 异步流的新版本在 Redis.StackExchange v2.1.0-preview.23 及更高版本中可用。
注意:如果您的 Redis 实例支持该功能,则此版本使用 SCAN 而不是 KEYS。这是一个巨大的性能提升。您还应该确保 ConnectionMultiplexer
的实例是单例 - 即在应用程序的生命周期中使用相同的实例。
我还应该指出,Redis 通配符支持允许非常灵活的模式。在我的实现中(如下),我只需要在键的末尾有一个“*”,所以这就是它的全部编码。如果您需要额外的通配符支持,您可以在此处实现 Redis wildcard supported glob-style patterns:
- h?llo matches hello, hallo and hxllo
- h*llo matches hllo and heeeello
- h[ae]llo matches hello and hallo, but not hillo
- h[^e]llo matches hallo, hbllo, ... but not hello
- h[a-b]llo matches hallo and hbllo
Use \ to escape special characters if you want to match them verbatim.
using Microsoft.Extensions.Caching.Distributed;
using StackExchange.Redis;
private readonly IDistributedCache _cache;
private readonly IConnectionMultiplexer _connectionMultiplexer;
public CacheRepository(IDistributedCache cache, IConnectionMultiplexer connectionMultiplexer)
{
_cache = cache;
_connectionMultiplexer = connectionMultiplexer;
}
public async Task RemoveWithWildCardAsync(string keyRoot)
{
if (string.IsNullOrWhiteSpace(keyRoot))
throw new ArgumentException("Value cannot be null or whitespace.", nameof(keyRoot));
// get all the keys* and remove each one
await foreach (var key in GetKeysAsync(keyRoot + "*"))
{
await _cache.RemoveAsync(key);
}
}
public async IAsyncEnumerable<string> GetKeysAsync(string pattern)
{
if (string.IsNullOrWhiteSpace(pattern))
throw new ArgumentException("Value cannot be null or whitespace.", nameof(pattern));
foreach (var endpoint in _connectionMultiplexer.GetEndPoints())
{
var server = _connectionMultiplexer.GetServer(endpoint);
await foreach (var key in server.KeysAsync(pattern: pattern))
{
yield return key.ToString();
}
}
}
public IEnumerable<RedisFeatures> GetRedisFeatures()
{
foreach (var endpoint in _connectionMultiplexer.GetEndPoints())
{
var server = _connectionMultiplexer.GetServer(endpoint);
yield return server.Features;
}
}
我花了一些时间没有得到任何钥匙
对于模式,使用类似这样的东西。
server.Keys(pattern: "*Error.*")
您应该在图案前后添加星星。
我有一个格式的密钥:
Error.1
Error.24
Error.32
使用 StackExchange.Redis
,我将如何处理所有匹配格式 Error.
的键的 KeyDelete
?
在另一个答案中,我看到了 LUA 脚本:
EVAL "return redis.call('del', unpack(redis.call('keys', ARGV[1])))" 0 Error.*
但我不确定如何使用 Database.ScriptEvaluate()
只需获取所有与模式匹配的键,迭代并删除,就像这样:
using (var redisConnection = ConnectionMultiplexer.Connect(...))
{
var server = redisConnection.GetServer(endpoint:...);
if (server != null)
{
foreach (var key in server.Keys(pattern: "Error.*"))
{
redisConnection.Database.KeyDelete(key);
}
}
}
稍后编辑:
设置Redis连接的例子:https://gist.github.com/cristipufu/9ad47caf3dba60d712484d0c880597b9
应该存储和重复使用多路复用器,而不是每次都丢弃和重新创建。 https://stackexchange.github.io/StackExchange.Redis/Basics
通过调整/指定 Keys 调用的 pageSize 参数可以显着提高性能。它的默认值为 10。尝试 1,000。
StackExchange.Redis server.Keys(pattern:"IsVerySlow*")
并且 通过 IAsyncEnumerable
使用 C# 异步流的新版本在 Redis.StackExchange v2.1.0-preview.23 及更高版本中可用。
注意:如果您的 Redis 实例支持该功能,则此版本使用 SCAN 而不是 KEYS。这是一个巨大的性能提升。您还应该确保 ConnectionMultiplexer
的实例是单例 - 即在应用程序的生命周期中使用相同的实例。
我还应该指出,Redis 通配符支持允许非常灵活的模式。在我的实现中(如下),我只需要在键的末尾有一个“*”,所以这就是它的全部编码。如果您需要额外的通配符支持,您可以在此处实现 Redis wildcard supported glob-style patterns:
- h?llo matches hello, hallo and hxllo
- h*llo matches hllo and heeeello
- h[ae]llo matches hello and hallo, but not hillo
- h[^e]llo matches hallo, hbllo, ... but not hello
- h[a-b]llo matches hallo and hbllo
Use \ to escape special characters if you want to match them verbatim.
using Microsoft.Extensions.Caching.Distributed;
using StackExchange.Redis;
private readonly IDistributedCache _cache;
private readonly IConnectionMultiplexer _connectionMultiplexer;
public CacheRepository(IDistributedCache cache, IConnectionMultiplexer connectionMultiplexer)
{
_cache = cache;
_connectionMultiplexer = connectionMultiplexer;
}
public async Task RemoveWithWildCardAsync(string keyRoot)
{
if (string.IsNullOrWhiteSpace(keyRoot))
throw new ArgumentException("Value cannot be null or whitespace.", nameof(keyRoot));
// get all the keys* and remove each one
await foreach (var key in GetKeysAsync(keyRoot + "*"))
{
await _cache.RemoveAsync(key);
}
}
public async IAsyncEnumerable<string> GetKeysAsync(string pattern)
{
if (string.IsNullOrWhiteSpace(pattern))
throw new ArgumentException("Value cannot be null or whitespace.", nameof(pattern));
foreach (var endpoint in _connectionMultiplexer.GetEndPoints())
{
var server = _connectionMultiplexer.GetServer(endpoint);
await foreach (var key in server.KeysAsync(pattern: pattern))
{
yield return key.ToString();
}
}
}
public IEnumerable<RedisFeatures> GetRedisFeatures()
{
foreach (var endpoint in _connectionMultiplexer.GetEndPoints())
{
var server = _connectionMultiplexer.GetServer(endpoint);
yield return server.Features;
}
}
我花了一些时间没有得到任何钥匙
对于模式,使用类似这样的东西。
server.Keys(pattern: "*Error.*")
您应该在图案前后添加星星。