【问题标题】:Is there an established pattern for paging in Service Fabric ReliableCollectionsService Fabric Reliable Collections 中是否有既定的分页模式
【发布时间】:2017-04-21 20:49:54
【问题描述】:

在可靠集合(特别是 IReliableDictionary)中,实现“常见”查询的一种方法是更新辅助字典,该字典将键构造为在枚举中以特定方式排序。对于大型数据集,我希望避免穿梭大量数据

为了实现这一点,我想实现某种延续令牌,调用者可以在请求数据时提供给我。我目前正在通过首先生成一个有序枚举并返回前 n 个项目来实现这一点,其中 n = MAX_PAGE 大小。 延续本质上是 n 项列表中的最后一个键。下次调用者传入延续令牌时,我使用过滤器函数生成有序可枚举,指定键应大于延续

这有两个问题(我可以看到):

  1. 集合可能会在调用者首次请求页面和后续请求之间发生变化。我不确定我是否可以避免这种情况,因为无论谁试图翻阅数据,都需要能够随时更新集合。
  2. 我不确定如何使用过滤器功能。我假设由于开发人员可以过滤任何内容,GetEnumerableAsync() 方法必须在返回可枚举之前提供字典中的所有键。对于足够大的数据集,这似乎很慢。

对于这样的分页数据是否有任何规定的方法?我开始觉得我可能会在我的某些用例中使用 Reliable Collections 找出错误的树。

【问题讨论】:

    标签: azure microservices azure-service-fabric service-fabric-stateful


    【解决方案1】:

    我有一个类似的问题,它还涉及对来自多个分区的数据进行过滤和排序。

    我的计划是使用通知在非分区状态服务中构建索引视图。在这里,我将有多个具有不同键的字典,其中每个键是一个或多个可以过滤或排序的属性,值是一个排序的 ID 列表。

    基本上,我计划对这些键进行搜索、排序和分页,然后在最后一步,我使用需要返回到原始分区的页面的 ID,并从那里获取这些 ID 的完整数据(这也可以通过不同的无状态服务来完成)。

    此方法不提供数据一致性,因为查询的数据在后续分页之间可能会发生变化。

    它一定比带有快照和延续令牌的要慢,但也许值得一试。

    【讨论】:

      【解决方案2】:

      构建二级索引的一种方法是使用Notifications。使用具有引用类型 TKey 和 TValue 的通知,您可以维护二级索引,而无需创建 TKey 或 TValue 的任何副本。

      如果需要二级索引提供快照隔离,那么二级索引选择的数据结构必须实现多版本并发控制。

      如果您没有这样的数据结构来托管二级索引,另一种选择是在分页客户端调用中保持事务和枚举的实时性。这样,您可以使用 Reliable Dictionary 的内置快照支持来提供对数据的分页一致扫描,而不会阻塞写入。在这种情况下,令牌将是TransactionId,允许您的服务找到与MoveNextAsync 相关的枚举。使用此选项的缺点是 Reliable Dictionary 将无法修剪由可能长时间运行的快照事务保持可见的旧版本值。

      为了减轻上述缺点,您可能希望限制正在进行的快照事务的数量以及客户端在您的服务处理枚举和相关读取事务之前完成分页枚举的时间。

      CreateEnumerableAsync 使用带有键过滤器时,Reliable Dictionary 将为每个键调用过滤器,以查看它是否满足自定义过滤器。由于今天 TKeys 始终保存在内存中,因此对于大多数关键过滤器,我们在这里没有看到问题。枚举中最昂贵的部分往往是从磁盘检索分页值。

      【讨论】:

      • 当您说“在这种情况下令牌将是 TransactionID”时,这是否意味着有一种机制可以从 transactionId 创建事务,或者您只是说我可以存储 ITransaction/IAsyncEnumerable在服务中某处的字典中?如果是后者——这能承受复制品的倒塌吗?
      • 我的意思是后者 @JustinBlakley :将 ITransaction 和 IAsyncEnumerable 存储在允许您使用 TransactionId 索引的数据结构中。在故障转移的情况下,在失败的副本上启动的所有正在进行的事务都将中止。
      • 这是有道理的@MertCoskun,我想我可以做的最后一个优化是在延续令牌中也包含返回的最后一个键。这样,在副本故障转移的情况下,我可以从性能下降的地方继续。 - 尽管给定一个足够大的密钥集,最好将错误返回给调用者并让它决定要做什么。
      • @JustinBlakley ,请记住,初始副本上的事务正在跟踪此枚举(快照视图)中可见的内容,并确保此事务可见的旧版本不会被垃圾收集。尝试为下一次分页读取提供服务的新副本将没有此事务。此外,它创建的新事务将具有不同的快照视图(因为它是在不同的逻辑时间拍摄的)。因此,您不仅不能保证对客户端的快照隔离,还必须处理新副本可能没有最后读取密钥的情况。
      猜你喜欢
      • 2019-09-03
      • 2018-01-09
      • 2017-05-08
      • 2016-06-28
      • 2018-03-15
      • 2012-07-16
      • 1970-01-01
      • 2017-11-09
      • 2018-12-08
      相关资源
      最近更新 更多