如何解决检索和反序列化大量Redis缓存项目
我们拥有这个核心实体,每次会话获取了很多次。该实体由13列组成,其中大多数字符少于20个字符。通常,它是通过父ID检索的,但有时是通过ID列表获取的子集。为了解决这个问题,我们正在考虑实施以下解决方案,但是问题是,这是否是一个好主意?通常,该列表大约有400个项目,但在某些情况下,可能多达3000个项目。
我们将使用以下密钥模式将实例存储在列表中:EntityName:{ParentId}:{ChildId}
,其中ParentId
和ChildId
是整数。
然后基于ParentId
检索列表,我们将使用EntityName:{ParentId}:*
作为pattern-argument的值调用以下方法:
public async Task<List<T>> GetMatches<T>(string pattern)
{
var keys = _multiPlexer.GetServer(_multiPlexer.GetEndPoints(true)[0]).Keys(pattern: pattern).ToArray();
var values = await Db.StringGetAsync(keys: keys);
var result = new List<T>();
foreach (var value in values.Where(x => x.HasValue))
{
result.Add(JsonSerializer.Deserialize<T>(value));
}
return result;
}
public async Task<List<T>> GetList<T>(string[] keys)
{
var values = await Db.StringGetAsync(keys: keys.Select(x => (RedisKey)x).ToArray());
var result = new List<T>();
foreach (var value in values.Where(x => x.HasValue))
{
result.Add(JsonSerializer.Deserialize<T>(value));
}
return result;
}
这里明显的担心是要反序列化的对象数量和System.Text.Json
的性能。
一种替代方法是将数据存储两次,既作为列表,也可以单独存储,但这仅在我们通过ParentId
获取数据的情况下才有用。我们也只能将数据存储为列表,并且每次都仅有时使用子集来检索它。
非常感谢所有输入!谢谢!
我编写了一个小型控制台应用程序,以对替代项进行负载测试,使用模式匹配,以2020ms的时间获取2000项100次,而获取列表的时间为1568ms。我认为我们可以忍受这种差异,并进行模式匹配。
解决方法
@Xerillio似乎是正确的。我使用托管服务进行了一些负载测试,然后使用模式匹配来获取列表要慢将近三倍,然后再直接从SQL接收列表就慢了三倍。因此,要回答我自己的问题,如果这是个好主意,我会说不,不是。大部分增加的时间不是因为反序列化,而是因为使用模式匹配来获取密钥。
这是从一个循环中获取2000个项目100个项目的结果:
- 直接从db = 8625ms获取
- 使用精确键列表= 5663ms进行提取
- 使用match = 13098ms提取
- 获取完整列表= 5352ms
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。