从Redis缓存数据库获取所有密钥

问题描述 投票:0回答:7

我正在使用 Redis 缓存进行缓存(特别是

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

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

Redis 文档讨论了 KESY 命令,但

stackexchange.Redis
确实有该命令的实现。

通过

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

有什么想法吗?

c# caching stackexchange.redis
7个回答
26
投票

您需要的功能在IServer接口下,可以通过以下方式实现:

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

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


14
投票
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();

9
投票

尝试使用此代码片段,它对我有用:

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

来源


7
投票

一旦您拥有了 IDatabase 实例,我就正在使用它:

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

5
投票

你需要db来区分在哪里寻找key。所以 MTZ4 答案的最后一行就变成:

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

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


3
投票

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 实例相对于我的环境的连接信息/字符串的方法。您可以在这里采用自己的方式,或者如果您愿意,也可以在这里对其进行硬编码。

方法1

因此,具备上述内容后,就可以将 Redis

IConnectionMultiplexer
注入您的
Controllers
Services

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
}

现在上面是

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

意味着如果您的目的仅限于

set
和/或
get
缓存作为
key-value pair
,您宁愿在下面的
Method 2
中这样做。

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

0
投票
现在是

2024

,这将为您提供所有端点的所有密钥以及密钥类型。作为示例,我使用了 
String
Hash
 类型,因此我将在这里仅显示这两种类型,其余的您可以根据需要填写。

初始化连接

//Configure this yourself or leave if testing locally via docker/local instance var options = new ConfigurationOptions { EndPoints = { "localhost" }, Password = "", Ssl = false }; var cache = ConnectionMultiplexer.Connect(options).GetDatabase(); await GetAllEndpointsAndKeys(cache);
public static async Task GetAllEndpointsAndKeys(IDatabase cache)
{
    //Get all endpoints (useful if you have distributed environment)
    var endPoints = cache.Multiplexer.GetEndPoints();
    int i = 1;
    foreach (var endPoint in endPoints)
    {
        Console.WriteLine(
            $"Fetching Endpoint No.{i++} - {endPoint} with Address Family as '{endPoint.AddressFamily}'"
        );

        var server = cache.Multiplexer.GetServer(endPoint);

        //Get all keys for this endpoint server instance
        var keys = server.Keys();

        foreach (var keyVar in keys)
        {            
            var redisKeyType = await cache.KeyTypeAsync(keyVar);

            switch (redisKeyType)
            {
                case RedisType.None:
                    break;
                case RedisType.String:
                    Console.WriteLine("\t*******************");
                    Console.WriteLine("\tNow adding string get");
                    Console.WriteLine("\t" + await cache.StringGetAsync(keyVar));
                    Console.WriteLine("\t *******************");
                    break;
                case RedisType.List:
                    break;
                case RedisType.Set:
                    break;
                case RedisType.SortedSet:
                    break;

                case RedisType.Hash:
                    Console.WriteLine("\t*******************");
                    foreach (var hashget in await cache.HashGetAllAsync(keyVar))
                    {
                        Console.WriteLine($"\tNow adding hash value");

                        Console.WriteLine(
                            "\t" + await cache.HashGetAsync(keyVar, hashget.Name)
                        );
                    }
                    Console.WriteLine("\t*******************");
                    break;
                case RedisType.Stream:
                    break;
                case RedisType.Unknown:
                    break;
                default:
                    break;
            }
        }
    }
}
    
© www.soinside.com 2019 - 2024. All rights reserved.