代码之家  ›  专栏  ›  技术社区  ›  teeboy

azure服务结构可靠字典linq查询非常慢

  •  4
  • teeboy  · 技术社区  · 9 年前

    我有一个可靠的服务结构有状态服务词典。我有一个简单的linq表达式。
    我使用Ix异步包来构建一个异步枚举。


    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();
    
    
            }  
    

    数据被组织为两个分区,每个分区中大约有75000条记录。我使用Int64范围作为分区键。在上面的代码中,“Result.ToList()”对每个分区执行大约需要1分钟。另一个奇怪的事情是,实际结果是空的!。在sql server中运行的同一sql将返回客户名以“c”结尾的行。但是,这不是重点。我最关心的是“ReliableDictionary”linq查询的性能。
    当做

    1 回复  |  直到 9 年前
        1
  •  7
  •   Mert Coskun - MSFT    9 年前

    可靠的字典定期从内存中删除最近使用最少的值。这是为了使

    • 大型可靠词典
    • 更高密度:每个副本的可靠收集密度更高,每个节点的副本密度更高。

    折衷是,这会增加读取延迟:需要磁盘IO来检索未缓存在内存中的值。

    有几个选项可以降低枚举的延迟。

    键筛选枚举 CreateEnumerbleAsync 采用密钥筛选器的重载。键过滤器允许可靠的字典避免从磁盘检索与查询不匹配的键的值。这种方法的一个限制是TKey(因此其中的字段)无法更新。

    使用通知的内存辅助索引 : Reliable Dictionary Notifications 可用于构建任意数量的二级索引。您可以构建一个二级索引,将所有值保存在内存中,从而交换内存资源以提供更低的读取延迟。此外,由于您可以完全控制辅助索引,因此可以保持辅助索引的有序性(例如,在您的示例中,通过与NameFirst相反)。

    我们还正在考虑使可靠字典的内存TValue扫描策略可配置。这样,您将能够配置可靠的字典,以便在读取延迟是您的优先事项时将所有值保留在内存中。

    由于在您的场景中,枚举中的大部分时间都花在磁盘IO上,因此您还可以使用 Custom Serializer 这可以减少磁盘和网络占用。

    谢谢你的提问。