Redis,StackExchange,与MGET合作,一次获得许多密钥

时间:2016-11-08 15:12:09

标签: redis stackexchange.redis

有没有办法在StackExchange Redis(C#)中使用MGET?

我需要一种方法来在一次通话中使用多个键。

2 个答案:

答案 0 :(得分:8)

可以使用下一个方法

 Task<RedisValue[]> StringGetAsync(RedisKey[] keys, CommandFlags flags = CommandFlags.None);

在StackExchange的DLL中。 给出一组Keys并接收Redis值数组。

答案 1 :(得分:1)

您可以使用StringGetAsync,但如果密钥量很大,可能会导致服务器超载。您可以使用下面的功能,该功能将通过每页50000个键进行分页来获取所有键

public async Task<Dictionary<string, T>> GetManyAsync<T>(ICollection<string> ids, int dbIndex)
{
        var semaphore = new SemaphoreSlim(1);
        var rs = await ids.ToRedisKeys()
            .ToObservable()
            .Buffer(50000)
            .SelectMany(async keysPage =>
            {
                try
                {
                    await semaphore.WaitAsync();
                    var redisValues = await DoRead(_ => _.StringGetAsync(keysPage.ToArray()), dbIndex);
                    return redisValues.Select(_ => serializer.Deserialize<T>(_));
                }
                finally
                {
                    semaphore.Release();
                }
            }).SelectMany(_ => _).ToList();
        return ids.Zip(rs, (i, r) => new { i, r }).ToDictionary(_ => _.i, _ => _.r);
}

测试此功能:

    [Fact]
    public async Task test_redis_paging()
    {
        var source = Observable.Range(1, 5);
        var kvp = await source.Buffer(3).SelectMany(async ls =>
         {
             string msg = $"item: {ls.First()}; thread {Thread.CurrentThread.ManagedThreadId}";
             Console.Out.WriteLine(DateTime.Now.TimeOfDay + msg + " started:");
             await Task.Delay(1000);
             Console.Out.WriteLine(DateTime.Now.TimeOfDay + msg + " finished:");

             return ls;

         }).SelectMany(_=>_).ToList();
         (kvp.Count()).Should().Be(5);
    }