StackExchange Redis(C#)でMGETを使用する方法はありますか?Redis、StackExchange、MGETで作業し、一度に多数のキーを取得する
私は、1回の呼び出しで多数のキーをリードする方法が必要です。
StackExchange Redis(C#)でMGETを使用する方法はありますか?Redis、StackExchange、MGETで作業し、一度に多数のキーを取得する
私は、1回の呼び出しで多数のキーをリードする方法が必要です。
次の方法StackExchangeのDLLで
Task<RedisValue[]> StringGetAsync(RedisKey[] keys, CommandFlags flags = CommandFlags.None);
を使用することが可能です。 キーの配列を与え、Redis値の配列を受け取ります。
StringGetAsyncを使用できますが、膨大な量のキーがある場合にサーバーのオーバーロードが発生する可能性があります。
[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);
}
:あなたはこの機能のためにページごとに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);
}
テストをページングですべてのキーを取得することを下記の機能を使用することができます