我正在使用包含约 100 万个键的可靠字典来评估 Service Fabric 的性能。我得到的结果相当令人失望,所以我想检查我的代码或我的期望是否错误。
我有一本初始化的字典dict = await _stateManager.GetOrAddAsync<IReliableDictionary2<string, string>>("test_"+id);
id
每次测试运行都是唯一的。
我用一个字符串列表填充它,比如
“1-1-1-1-1-1-1-1-1”,
“1-1-1-1-1-1-1-1-2”,
“1-1-1-1-1-1-1-1-3”......多达 576,000 项。字典中的值没有被使用,我目前只使用“1”。
将所有项目添加到词典中大约需要 3 分钟。我必须一次将交易拆分为100,000,否则它似乎永远挂起(在需要之前,交易中的操作数量是否有限制)CommitAsync()
?)
//take100_000 is the next 100_000 in the original list of 576,000
using (var tx = _stateManager.CreateTransaction())
{
foreach (var tick in take100_000) {
await dict.AddAsync(tx, tick, "1");
}
await tx.CommitAsync();
}
之后,我需要遍历字典来访问每个项目:
using (var tx = _stateManager.CreateTransaction())
{
var enumerator = (await dict.CreateEnumerableAsync(tx)).GetAsyncEnumerator();
try
{
while (await enumerator.MoveNextAsync(ct))
{
var tick = enumerator.Current.Key;
//do something with tick
}
}
catch (Exception ex)
{
throw ex;
}
}
这需要 16 秒。
我不太关心写入时间,我知道它必须被复制和持久化。但为什么要花这么长时间来阅读呢? 576,000 个 17 个字符的字符串键在内存中不应超过 11.5mb,并且值只是单个字符并被忽略。 Reliable Collections 不是缓存在 RAM 中吗?迭代相同值的常规字典需要 13 毫秒。
然后我打电话ContainsKeyAsync
空字典上 576,000 次(在 1 个事务中)。这花了 112 秒。在任何其他数据结构上尝试此操作可能需要大约 0 毫秒。
这是在本地 1 节点集群上。当部署到 Azure 时,我得到了类似的结果。
这些结果可信吗?我应该检查任何配置吗?我是否做错了什么,或者我的期望非常不准确?如果是这样,是否有更适合这些要求的东西? (约 100 万个小键,无值,持续事务更新)