azure service fabric 可靠字典 linq 查询非常慢
azure service fabric reliable dictionary linq query very slow
我在服务结构有状态服务中有一本可靠的字典。我有一个简单的 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 服务器 returns 行中相同的 sql 运行,客户名字以 "c" 结尾。但是,这不是重点。我最关心的是 "ReliableDictionary" linq 查询的性能。
此致
Reliable Dictionary 会定期从内存中删除最近最少使用的值。这是为了启用
- 大型可靠词典
- 更高密度:每个副本的可靠集合密度更高,每个节点的副本密度更高。
权衡是,这会增加读取延迟:需要磁盘 IO 来检索未缓存在内存中的值。
有几个选项可以降低枚举的延迟。
1) Key Filtered Enumeration:您可以将要在查询中使用的字段移动到 ReliableDictionary 的 TKey(上例中的 NameFirst)。这将允许您使用接受密钥过滤器的 CreateEnumerbleAsync 重载。键过滤器允许 Reliable Dictionary 避免从磁盘中检索与您的查询不匹配的键的值。这种方法的一个限制是无法更新 TKey(因此其中的字段)。
2) 使用通知的内存中二级索引:Reliable Dictionary Notifications 可用于构建任意数量的二级索引。您可以构建一个二级索引,将所有值保存在内存中,从而交易内存资源以提供更低的读取延迟。此外,由于您可以完全控制二级索引,因此可以保持二级索引有序(例如,在您的示例中通过 NameFirst 的反向)。
我们也在考虑使 Reliable Dictionary 的内存中 TValue 扫描策略可配置。有了这个,如果读取延迟是您的优先事项,您将能够配置 Reliable Dictionary 以将所有值保存在内存中。
由于在您的方案中,枚举的大部分时间都花在了磁盘 IO 上,因此您也可以从使用 Custom Serializer 中获益,这可以减少磁盘和网络占用空间。
感谢您的提问。
我在服务结构有状态服务中有一本可靠的字典。我有一个简单的 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 服务器 returns 行中相同的 sql 运行,客户名字以 "c" 结尾。但是,这不是重点。我最关心的是 "ReliableDictionary" linq 查询的性能。
此致
Reliable Dictionary 会定期从内存中删除最近最少使用的值。这是为了启用
- 大型可靠词典
- 更高密度:每个副本的可靠集合密度更高,每个节点的副本密度更高。
权衡是,这会增加读取延迟:需要磁盘 IO 来检索未缓存在内存中的值。
有几个选项可以降低枚举的延迟。
1) Key Filtered Enumeration:您可以将要在查询中使用的字段移动到 ReliableDictionary 的 TKey(上例中的 NameFirst)。这将允许您使用接受密钥过滤器的 CreateEnumerbleAsync 重载。键过滤器允许 Reliable Dictionary 避免从磁盘中检索与您的查询不匹配的键的值。这种方法的一个限制是无法更新 TKey(因此其中的字段)。
2) 使用通知的内存中二级索引:Reliable Dictionary Notifications 可用于构建任意数量的二级索引。您可以构建一个二级索引,将所有值保存在内存中,从而交易内存资源以提供更低的读取延迟。此外,由于您可以完全控制二级索引,因此可以保持二级索引有序(例如,在您的示例中通过 NameFirst 的反向)。
我们也在考虑使 Reliable Dictionary 的内存中 TValue 扫描策略可配置。有了这个,如果读取延迟是您的优先事项,您将能够配置 Reliable Dictionary 以将所有值保存在内存中。
由于在您的方案中,枚举的大部分时间都花在了磁盘 IO 上,因此您也可以从使用 Custom Serializer 中获益,这可以减少磁盘和网络占用空间。
感谢您的提问。