在可靠的集合(特别是IReliableDictionary)中,实现“常见”查询的方法是更新辅助字典,该字典构造要在枚举中以特定方式排序的键。对于大型数据集,我希望避免绕过大量数据。
为了达到这个目的,我想实现某种延续令牌,在请求数据时调用者可以提供给我。我目前正在实现这一点,首先生成一个有序枚举并返回前n个项,其中n = MAX_PAGE大小。 延续本质上是n个项目列表中的最后一个键。下一次调用者传入延续令牌时,我使用过滤器函数生成有序枚举,指定键应该大于延续。
这有两个问题(我可以看到):
是否有任何规定的方法来分页这样的数据?我开始觉得我可能会因为某些用例而使用Reliable Collections咆哮错误的树。
答案 0 :(得分:3)
建立次要指标的一种方法是使用Notifications。使用带引用类型TKey&的通知TValue,您可以维护二级索引,而无需创建TKey或TValue的任何副本。
如果您需要辅助索引来提供快照隔离,那么为辅助索引选择的数据结构必须实现多版本并发控制。
如果您没有这样的数据结构来托管二级索引,另一个选择是在分页客户端调用中保持事务和枚举。这样,您可以使用Reliable Dictionary的内置快照支持,在不阻止写入的情况下对数据提供分页一致扫描。在这种情况下,令牌将是TransactionId,允许您的服务在MoveNextAsync上找到相关的枚举。使用此选项的缺点是,Reliable Dictionary将无法修剪可能长时间运行的快照事务保持可见的旧版本值。
为了缓解上述缺点,您可能希望在服务处理枚举和相关读取事务之前,限制正在进行的快照事务的数量以及客户端完成分页枚举的时间。
当使用带有密钥过滤器的CreateEnumerableAsync时,Reliable Dictionary将为每个密钥调用过滤器,以查看它是否满足自定义过滤器。由于今天TKeys总是保留在内存中,对于大多数关键过滤器,我们在这里没有看到问题。枚举中最昂贵的部分往往是从磁盘中检索分页值。
答案 1 :(得分:0)
我遇到了类似的问题,它还涉及对来自多个分区的数据进行过滤和排序。
我的计划是使用通知在非分区的有状态服务中构建索引视图。在这里,我将有多个具有不同键的字典,其中每个键是一个或多个可以过滤或排序的属性,值是一个已排序的ID列表。
基本上,我计划对这些密钥进行搜索,排序和分页,然后在最后一步,我使用需要返回到原始分区的页面的ID,并从那里获取这些ID的完整数据(这可以通过不同的无状态服务来完成。)
此方法不提供数据一致性,因为查询的数据可以在后续分页之间更改。
它必须比具有快照和延续令牌的速度慢,但也许值得尝试。