这是 StackExchange Redis 流水线的良好实现吗?
Is this a good implementation of StackExchange Redis pipelining?
我从 REDIS 和 StackExchange Redis 客户端开始。我想知道我是否获得了从 REDIS 一次获取多个项目的最佳性能。
情况:
我有一个 ASP.NET MVC 网络应用程序,它在用户的仪表板上显示个人日历。因为仪表板是它被大量使用的登录页面。
为了显示日历项,我首先获取该特定月份的所有日历项 ID:
RedisManager.RedisDb.StringGet("calendaritems_2016_8");
// this returns JSON Serialized List<int>
然后,对于每个日历项 ID,我构建一个对应缓存键的列表:
"CalendarItemCache_1"
"CalendarItemCache_2"
"CalendarItemCache_3"
etc.
通过这个集合,我使用通用函数访问了 REDIS:
var multipleItems = CacheHelper.GetMultiple<CalendarItemCache>(cacheKeys);
实现方式如下:
public List<T> GetMultiple<T>(List<string> keys) where T : class
{
var taskList = new List<Task>();
var returnList = new ConcurrentBag<T>();
foreach (var key in keys)
{
Task<T> stringGetAsync = RedisManager.RedisDb.StringGetAsync(key)
.ContinueWith(task =>
{
if (!string.IsNullOrWhiteSpace(task.Result))
{
var deserializeFromJson = CurrentSerializer.Serializer.DeserializeFromJson<T>(task.Result);
returnList.Add(deserializeFromJson);
return deserializeFromJson;
}
else
{
return null;
}
});
taskList.Add(stringGetAsync);
}
Task[] tasks = taskList.ToArray();
Task.WaitAll(tasks);
return returnList.ToList();
}
我实施流水线是否正确? REDIS CLI 监视器显示:
1472728336.718370 [0 127.0.0.1:50335] "GET" "CalendarItemCache_1"
1472728336.718389 [0 127.0.0.1:50335] "GET" "CalendarItemCache_2"
etc.
我期待某种 MGET 命令。
非常感谢。
我注意到一个接受 RedisKey[] 的 StringGet 重载方法。使用它,我在监视器中看到一个 MGET 命令。
public List<T> GetMultiple<T>(List<string> keys) where T : class
{
List<RedisKey> list = new List<RedisKey>(keys.Count);
foreach (var key in keys)
{
list.Add(key);
}
RedisValue[] result = RedisManager.RedisDb.StringGet(list.ToArray());
var redisValues = result.Where(x=>x.HasValue);
var multiple = redisValues.Select(x => DeserializeFromJson<T>(x)).ToList();
return multiple;
}
我从 REDIS 和 StackExchange Redis 客户端开始。我想知道我是否获得了从 REDIS 一次获取多个项目的最佳性能。
情况: 我有一个 ASP.NET MVC 网络应用程序,它在用户的仪表板上显示个人日历。因为仪表板是它被大量使用的登录页面。
为了显示日历项,我首先获取该特定月份的所有日历项 ID:
RedisManager.RedisDb.StringGet("calendaritems_2016_8");
// this returns JSON Serialized List<int>
然后,对于每个日历项 ID,我构建一个对应缓存键的列表:
"CalendarItemCache_1"
"CalendarItemCache_2"
"CalendarItemCache_3"
etc.
通过这个集合,我使用通用函数访问了 REDIS:
var multipleItems = CacheHelper.GetMultiple<CalendarItemCache>(cacheKeys);
实现方式如下:
public List<T> GetMultiple<T>(List<string> keys) where T : class
{
var taskList = new List<Task>();
var returnList = new ConcurrentBag<T>();
foreach (var key in keys)
{
Task<T> stringGetAsync = RedisManager.RedisDb.StringGetAsync(key)
.ContinueWith(task =>
{
if (!string.IsNullOrWhiteSpace(task.Result))
{
var deserializeFromJson = CurrentSerializer.Serializer.DeserializeFromJson<T>(task.Result);
returnList.Add(deserializeFromJson);
return deserializeFromJson;
}
else
{
return null;
}
});
taskList.Add(stringGetAsync);
}
Task[] tasks = taskList.ToArray();
Task.WaitAll(tasks);
return returnList.ToList();
}
我实施流水线是否正确? REDIS CLI 监视器显示:
1472728336.718370 [0 127.0.0.1:50335] "GET" "CalendarItemCache_1"
1472728336.718389 [0 127.0.0.1:50335] "GET" "CalendarItemCache_2"
etc.
我期待某种 MGET 命令。
非常感谢。
我注意到一个接受 RedisKey[] 的 StringGet 重载方法。使用它,我在监视器中看到一个 MGET 命令。
public List<T> GetMultiple<T>(List<string> keys) where T : class
{
List<RedisKey> list = new List<RedisKey>(keys.Count);
foreach (var key in keys)
{
list.Add(key);
}
RedisValue[] result = RedisManager.RedisDb.StringGet(list.ToArray());
var redisValues = result.Where(x=>x.HasValue);
var multiple = redisValues.Select(x => DeserializeFromJson<T>(x)).ToList();
return multiple;
}