使用 IReliableDictionary2 时数据何时持久保存到磁盘?

When is data persisted to disk when using IReliableDictionary2?

我们有一个实现 IReliableDictionary2 的 c# 可靠集合字典,并且由于序列化错误而注意到一些奇怪的事情。

我们有 Class X,其中包含另一个 class、Class Y。我们忘记将序列化添加到 Class Y。但是在 [=18 之后的几天=] X 被添加到可靠的集合字典中,Class 当我们检索 X 的实例时 Y 也在那里。

显然可靠的集合字典只是在内存中,但在某些时候集合被持久化到磁盘,此时 Class Y 返回 null 因为它没有添加到序列化 [数据成员].

所以问题是可靠集合何时持久化到磁盘?对此有程序控制吗?或者这是某种集群设置?

问题应该换个方向:当服务结构 从磁盘读取 集合时?

它在提交事务时将数据持久化(同时保存到磁盘和内存缓存中)。从磁盘读取数据可能有多种原因(例如主节点 changed/restarted ..)

当您使用 ReliableCollections 时,每个操作(即 AddAsync)执行以下操作:

  1. 更新ITransaction本地存储(提供read-your-own-writes semantics
  2. 序列化值并更新本地操作日志(持久化)。
  3. 将这些字节发送到所有辅助副本以确保它们具有相同的信息。

然后当 ITransaction 被提交时,commit 条目被附加到日志中并发送到所有辅助副本。在 quorum 确认提交的那一刻,操作被视为完成(请参阅 here 了解更多信息)。

所以一般来说,信息一直是序列化的。

您看到 'correct' 结果的原因是因为大多数时候您使用同一个副本 - 主副本(这样做是因为只有主副本可以修改状态)并且来自同一副本的所有读取/写入都返回 正确 值。

这里的技巧是 Service Fabric 可以在节点之间移动副本,即假设您的主副本在 Node1 上。您的所有读取和写入都很好,但 Service Fabric 决定将您的主副本移动到 Node2 - 这导致 Node2 上有一个新的空闲副本,通过向其传输序列化数据来获取 initialized .当副本初始化时,Node1 上的副本被降级,Node2 上的副本被提升。现在您所有的请求都是来自 Node2 而不是来自 Node1 的服务器(有关服务和副本生命周期的更多信息,请参阅 here and here)。

主要问题:When is data persisted to disk when using IReliableDictionary2? 在堆栈溢出和文档中已经有很多答案。

此答案详细说明了数据是如何更改和复制的:

这一个回答了它是如何存储在内存中的:

你的情况出现问题的原因很明确:

  1. 你没有正确序列化数据,当数据被复制到其他副本时它会丢失信息
  2. 正如许多其他问题和帖子中所解释的那样,数据存在于内存中,因此将这些数据写入磁盘并读取到内存是没有意义的,原始副本保存在内存中的完整数据,这是不同的来自复制的那个。
  3. 如果从副本变成主副本,加载到内存中的数据将丢失信息。
  4. Reliable Dictionary 还有 'caching' 将未使用的 "cold" 数据刷新到磁盘以释放内存,这是他们为更好地利用内存所做的改进之一,只要您的数据'long' 时间未使用,它们从内存中删除字典值,而不是键,以释放 space,当您再次访问数据时,它将从磁盘加载。