我在服务结构状态服务中有一个可靠的字典。我有一个简单的linq表达 我正在使用Ix-Async包来构建一个asyncenumerable。
using (ITransaction tx = this.StateManager.CreateTransaction())
{
var result = (await customers.CreateLinqAsyncEnumerable(tx))
.Where(x => x.Value.NameFirst != null && x.Value.NameFirst.EndsWith(n, StringComparison.InvariantCultureIgnoreCase))
.Select(y => y.Value);
return await result.ToList();
}
数据分为2个分区,每个分区约有75,000条记录。我使用Int64范围作为分区键。在上面的代码中," Result.ToList()"每个分区执行大约需要1分钟。另一个问题是,实际结果是空的!在sql server中运行的相同sql返回客户名字以" c"结尾的行。但是,这是重点。我最关心的是" ReliableDictionary" linq查询。
此致
答案 0 :(得分:7)
Reliable Dictionary定期从内存中删除最近最少使用的值。这是为了启用
权衡的是,这会增加读取延迟:磁盘IO需要检索未缓存在内存中的值。
有几种方法可以降低枚举的延迟。
1)密钥过滤枚举:您可以将要在查询中使用的字段移动到ReliableDictionary的TKey(上例中的NameFirst)。这将允许您使用密钥过滤器中的CreateEnumerbleAsync重载。密钥过滤器允许Reliable Dictionary避免从磁盘中检索与您的查询不匹配的密钥的值。这种方法的一个限制是TKey(因此其中的字段)无法更新。
2)使用通知的内存中二级索引:Reliable Dictionary Notifications可用于构建任意数量的二级索引。您可以构建一个二级索引,将所有值保存在内存中,从而交换内存资源,以提供更低的读取延迟。此外,由于您可以完全控制二级索引,因此可以保持二级索引的顺序(例如,在您的示例中,通过反向NameFirst)。
我们还在考虑制作Reliable Dictionary的内存中TValue扫描策略。有了这个,您将能够配置可靠字典,以便在读取延迟优先时保留所有值。
由于在您的方案中,枚举的大部分时间都花在了磁盘IO上,因此您也可以使用Custom Serializer来减少磁盘和网络占用空间。
感谢您的提问。