【问题标题】:Get all keys from Redis Cache database从 Redis Cache 数据库中获取所有密钥
【发布时间】:2016-09-23 00:23:16
【问题描述】:

我将 Redis 缓存用于缓存目的(特别是 stackexchange.Redis C# driver。想知道是否有任何方法可以随时获取缓存中可用的所有键。我的意思是我可以在 ASP.NET 中做类似的事情@ 987654323@对象(以下代码示例)

var keys = Cache.GetEnumerator();                               
while(keys.MoveNext())
{
     keys.Key.ToString() // Key
}

Redis documentation talks about KESY commandstackexchange.Redis 有该命令的实现。

通过connection.GetDataBase() 实例进行调试,我没有看到任何方法/属性。

有什么想法吗?

【问题讨论】:

  • 我想你需要的是 GetServer().Keys() 函数。
  • @Evk,是的......请把它作为答案发布。

标签: c# caching stackexchange.redis


【解决方案1】:

你需要的功能在IServer接口下,可以通过:

ConnectionMultiplexer m = CreateConnection();
m.GetServer("host").Keys();

请注意,在 2.8 版本之前的 redis 服务器将使用您提到的 KEYS 命令,并且在某些情况下可能会非常慢。但是,如果您使用 redis 2.8+ - 它将使用 SCAN 命令代替,它的性能更好。还要确保您真的需要获取所有密钥,在我的实践中,我从来不需要这个。

【讨论】:

    【解决方案2】:
    string connectionString = "my_connection_string";
    ConfigurationOptions options = ConfigurationOptions.Parse(connectionString);
    ConnectionMultiplexer connection = ConnectionMultiplexer.Connect(options);
    IDatabase db = connection.GetDatabase();
    EndPoint endPoint = connection.GetEndPoints().First();
    RedisKey[] keys = connection.GetServer(endPoint).Keys(pattern: "*").ToArray();
    

    【讨论】:

    • IDatabase db = connection.GetDatabase();此行似乎未使用。
    • 可能是……老实说我不记得了。如果可以,请检查并评论是否属实。
    【解决方案3】:

    尝试使用此代码 sn-p,它对我有用:

    IServer server = Connection.GetServer("yourcache.redis.cache.windows....", 6380);
    foreach (var key in server.Keys())
    {
       Console.WriteLine(key);
    }
    

    source

    【讨论】:

    • Tanvi,感谢您的回答,但您的回答与已经发布并接受的回答不一样吗?
    • 我尝试使用此处给出的答案中的方法,但它对我不起作用,所以我发布了我在其他地方找到的解决方案。
    • Tanvi,可能这对您不起作用,因为您按原样尝试过。这是一个发布的抽象代码,但确实指出了需要做的事情。无论您为发布工作代码所做的努力如何 +1。
    【解决方案4】:

    您需要 db 来区分在哪里查找密钥。所以MTZ4答案的最后一行就变成了:

    RedisKey[] keys = connection.GetServer(endPoint).Keys(database: db.Database, pattern: "*").ToArray();

    其中 db.Database 是您要查询的 Redis 数据库的数字标识符。

    【讨论】:

    • 指定数据库是关键!否则你总是会得到一个空集。
    【解决方案5】:

    ASP.Net Core 3.1

    将以下packages 添加到您的.csproj

    <ItemGroup>
      <PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="3.1.15" />
      <PackageReference Include="StackExchange.Redis.Extensions.AspNetCore" Version="7.0.1" />
      <PackageReference Include="StackExchange.Redis.Extensions.Core" Version="7.0.1" />
      <PackageReference Include="StackExchange.Redis.Extensions.Newtonsoft" Version="7.0.1" />
    </ItemGroup>
    

    Startup.cs 中,您可以通过这种方式注册Redis Client,以便将其注入您的工作流代码。

    public class Startup
    {
      public void ConfigureServices(IServiceCollection services)
      {
        // ... other registrations
    
        // Used By : Sample Below : RedisCacheHelperController (Method 1 Only)
        services.AddSingleton<IConnectionMultiplexer>(
                ConnectionMultiplexer.Connect(DbHelper.GetRedisConnectionHost(Options.IsDevDb()))
            );
    
        // Used By : Sample Below : DistributedCacheController (Method 2 Only)
        services.AddStackExchangeRedisCache(options => 
                options.Configuration = DbHelper.GetRedisConnectionHost(Options.IsDevDb())
            );
    
        // ... other registrations
      }
    }
    

    注意:

    DbHelper.GetRedisConnectionHost(Options.IsDevDb()) :>>> 是我根据我的环境为我的 Redis 实例解析连接信息/字符串的方法。你可以在这里有自己的方式,或者如果你愿意的话,你可以在这里硬编码。

    方法一

    因此,有了上述内容,就可以将 Redis IConnectionMultiplexer 注入您的 ControllersServices

    public class RedisCacheHelperController : ControllerBase
    {
        private readonly IConnectionMultiplexer multiplexer;
    
        public RedisCacheHelperController(IConnectionMultiplexer multiplexer)
        {
            this.multiplexer = multiplexer;
        }
    }
    

    这里有帮助程序 API 来演示如何使用 IConnectionMultiplexer

    public class RedisCacheHelperController : ControllerBase
    {
        private readonly IConnectionMultiplexer multiplexer;
    
        public RedisCacheHelperController(IConnectionMultiplexer multiplexer)
        {
            this.multiplexer = multiplexer;
        }
    
        [HttpGet("{key}")]
        public async Task<IActionResult> GetCacheByKey([FromRoute] string key)
        {
            var responseContent = await multiplexer.GetDatabase().StringGetAsync(key);
    
            return Content(
               responseContent,
               Constants.ContentTypeHeaderValueJson // "application/json"
           );
        }
    
        [HttpPost("{key}")]
        public async Task<IActionResult> PostCacheByKey([FromRoute] string key, [FromBody] object data)
        {
            var requestContent = data.Json(); // JsonConvert.SerializeObject(data)
            await multiplexer.GetDatabase().StringSetAsync(key, requestContent);
            return Ok(key);
        }
    
        [HttpDelete("{key}")]
        public async Task<IActionResult> DeleteCacheByKey([FromRoute] string key)
        {
            await multiplexer.GetDatabase().KeyDeleteAsync(key);
            return Ok(key);
        }
    
        [HttpGet("CachedKeys")]
        public IActionResult GetListCacheKeys([FromQuery] [DefaultValue("*")] string pattern)
        {
            var keys = multiplexer
                .GetServer(multiplexer
                    .GetEndPoints()
                    .First())
                .Keys(pattern: pattern ?? "*")
                .Select(x => x.Get());
    
            return Ok(keys);
        }
       
        // ... could have more Reids supported operations here
    }
    

    现在上面是您想要访问Redis Client 并执行更多Redis 特定工作的use-case。我们在上面的.csproj 中包含的包Microsoft.Extensions.Caching.StackExchangeRedis 支持ReidsIDistributedCache 的形式注册和注入。接口IDistributedCacheMicrosoft 定义,支持不同分布式缓存解决方案的基本/通用功能,Redis 就是其中之一。

    意思是如果您的目的仅限于set 和/或get 缓存作为key-value pair,您宁愿在下面的Method 2 中这样做。

    方法二

    public class DistributedCacheController : ControllerBase
    {
        private readonly IDistributedCache distributedCache;
    
        public DistributedCacheController(IDistributedCache distributedCache)
        {
            this.distributedCache = distributedCache;
        }
        
        [HttpPost("{key}")]
        public async Task<IActionResult> PostCacheByKey([FromRoute] string key, [FromBody] object data)
        {
            var requestContent = data.Json(); // JsonConvert.SerializeObject(data)
            await distributedCache.SetStringAsync(key, requestContent);
            return Ok(key);
        }
    
        [HttpGet("{key}")]
        public async Task<IActionResult> GetCacheByKey([FromRoute] string key)
        {
            var responseContent = await distributedCache.GetStringAsync(key);
    
            if (!string.IsNullOrEmpty(responseContent))
            {
                return Content(
                   responseContent,
                   Constants.ContentTypeHeaderValueJson // "application/json"
                );
            }
    
            return NotFound();
        }
    
        [HttpDelete("{key}")]
        public async Task<IActionResult> DeleteCacheByKey([FromRoute] string key)
        {
            await distributedCache.RemoveAsync(key);
            return Ok(key);
        }
    }
    

    【讨论】:

    • 我得到 RedisKey 不包含 Get() 的定义,知道吗?
    • 这显示了如何从 aspnetcore 使用 Redis,但没有回答如何枚举键的问题
    • Method1,向下滚动到API4 [HttpGet("CachedKeys")] 就是答案。不幸的是,IDistributedCache 没有为您提供获取所有密钥的机制。为此,您必须使用Method1
    【解决方案6】:

    一旦你有了你的 IDatabase 实例,我正在使用它:

            var endpoints = _Cache.Multiplexer.GetEndPoints();
            var server = _Cache.Multiplexer.GetServer(endpoints[0]);
            var keys = server.Keys();
    

    【讨论】:

    • 请不要发布仅代码的答案(基本上就是这样)。未来的读者将不胜感激看到解释为什么它回答了问题,而不是不得不从代码中推断出来。而且,由于这是一个老问题,请解释它如何补充其他答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-06
    • 2017-08-31
    • 1970-01-01
    • 2017-04-03
    • 1970-01-01
    相关资源
    最近更新 更多