我正在嘗試提高從 Redis 讀取哈希的性能,并且嘗試實作流水線,這是正確的方法嗎?
public Task FetchHashesFromRedis(List<string> redisKeys, CancellationToken cancellationToken)
{
var parallel = Environment.ProcessorCount;
var semafore = new SemaphoreSlim(initialCount: parallel, maxCount: parallel);
var tasks = new List<Task>();
for (int i = 0; i < redisKeys.Count; i )
{
var currentKey = redisKeys.ElementAt(i);
var task = FetchFromRedis(currentKey, semafore, cancellationToken)
tasks.Add(task);
}
return Task.WhenAll(tasks);
}
這段代碼有什么可以改進的?
uj5u.com熱心網友回復:
如果您使用異步 API 和一系列任務,StackExchange.Redis 將自動為您處理所有內容。您還需要確保在哈希的情況下利用 HSET/HMGET 命令的可變性來減少需要向 Redis 發出的原始命令的數量。
我不確定FetchFromRedis在您提供的代碼的背景關系中做了什么。假設它異步執行 HGET/HMGET/HGETALL 操作之一,并從中回傳任務,我懷疑你離得太遠了。但我還沒有看到你是如何把結果拉出來的?
以下代碼創建并從 Redis 中的 10k 哈希中獲取資料。這有點微不足道,但展示了您正在尋找的行為。在我的機器上(當然,我要去本地主機),這在大約 75 毫秒內執行 - 或大約 3.8 微秒/操作。完成后,結果都可以在 的任務中使用getTasks。
您需要確保(使用實際的資料加載)您不會過度推動它,因為粉碎 StackExchange.Redis 可能會導致它拋出超時例外(基本上如果您排隊太多東西操作可能會卡在多路復用器的訊息佇列中并失敗)。
var stopwatch = Stopwatch.StartNew();
var setTasks = new List<Task>();
for (var i = 1; i < 10000; i )
{
setTasks.Add(db.HashSetAsync($"hash:{i}", new HashEntry[]{new HashEntry("foo", "bar"), new HashEntry("baz", 3)}));
}
await Task.WhenAll(setTasks);
var getTasks = new List<Task<RedisValue[]>>();
for (var i = 1; i < 10000; i )
{
getTasks.Add(db.HashGetAsync($"hash:{i}", new RedisValue[]{"foo","baz"}));
}
await Task.WhenAll(getTasks);
stopwatch.Stop();
Console.Write($"total execution time:{stopwatch.ElapsedMilliseconds}");
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/476233.html
標籤:。网 雷迪斯 并行处理 stackexchange.redis 流水线
