恢复容器数据

在此场景中,我们探索数据恢复。 当容器达到无法进一步处理用户操作的无效状态时,我们认为数据会损坏。 损坏状态的结果是容器意外关闭。 通常这是暂时性状态,重新打开后,容器的行为可能会恢复正常。 如果容器在多次重试后仍无法加载,你可以使用我们提供的用于恢复数据的 API 和流,如下所示。

Fluid Framework 和 Azure Fluid Relay 如何保存状态

Fluid Framework 会定期在容器中保存数据的快照,该快照汇总了对数据所做的所有更改。 在正常加载期间,将检索最新的快照,并在该状态之上应用任何后续更改。

如果最新的快照或后续更改损坏,Fluid 可能无法正常加载它们。 在这种情况下,Fluid 会提供一组 API 来查看存储的快照版本,并在仅供查看模式下加载它们,且不应用后续更改。 这样,就可以提取数据并可选择是否将其注入到新容器中以恢复协作。

Azure 客户端 API

用于查看和加载容器版本的 API

AzureClient 具有以下支持此情况的方法:

获取容器版本

getContainerVersions(id, options?)

检索可用于加载数据的版本的列表。

Parameters:

  • id:容器 ID。 这与调用 getContainer 时使用的 ID 相同。
  • options?:(可选)要指定的选项对象:
    • maxCount:可检索的最大版本数。 如果可用版本多于所请求的版本,将检索最新版本。 默认:5

Returns: 一个承诺,将解析为表示可用版本的对象的数组(按从最新到最旧版本排序)。 这些对象具有以下属性:

  • id:版本 ID。
    • 注意:这不同于容器 ID,将专门引用快照版本而不是容器。
  • date:生成相应版本时的时间戳。

查看容器版本

viewContainerVersion(id, containerSchema, version, compatibilityMode)

加载容器的特定版本以仅供查看。 可以使用从 getContainerVersions 检索到的任何版本,但为了恢复损坏的数据,建议从最新版本开始向后查找最新的未损坏版本。

容器以暂停状态加载,这意味着它不会对数据应用生成该快照后发生的后续更改。 在此状态下加载时,可以读取容器数据,但不能进行编辑。

Parameters:

  • id:容器 ID。 这与调用 getContainer 时使用的 ID 相同。
  • containerSchema:容器架构。 这与调用 getContainer 时使用的架构相同。
  • version:引用要用于加载数据的版本的版本对象。 可以通过 getContainerVersions 检索版本对象。
  • compatibilityMode:兼容性模式。 这与调用 getContainer 时使用的兼容性模式相同。

Returns: 一个承诺,将解析为以单个属性表示已加载容器的对象:

  • container:容器对象。 这是与 getContainer 返回的容器对象相同类型的对象,但在所选版本之前的状态下暂停。

示例

const azureClient = new AzureClient(/* ... */);
const versions = await azureClient.getContainerVersions(id);
// Since the versions are sorted in order from newest to oldest, versions[0] will attempt to load the most recent version.
// If the most recent version is corrupted, we could try again with versions[1] and so on to find the most-recent uncorrupted version.
const { container } = await azureClient.viewContainerVersion(id, containerSchema, versions[0], "2");

// We can now start reading the data from the container.
const someData = container.initialObjects.someSharedMap.get("hello");

// With the data extracted, we can inject it into a new uncorrupted container and attach it to start collaborating again.
const { container: newContainer } = await azureClient.createContainer(containerSchema, "2");
newContainer.initialObjects.someSharedMap.set("hello", someData);
const newId = await newContainer.attach();

关键观测结果

我们正在创建新容器

我们不会恢复(回滚)现有容器。 copyContainer 将为我们提供新实例,新实例的数据从原始容器复制。 在此过程中,不会删除旧容器。

已拆离新容器

新容器最初处于“detached”状态。 我们可以继续使用拆离的容器,也可以立即附加它。 调用 attach 后,我们将获得唯一的容器 ID,它表示新创建的实例。

恢复后注意事项

当涉及到围绕恢复后场景构建用例时,关于应用程序可能需要做些什么来让远程协作者再次在同一个容器上正常工作,这里有几个注意事项。

如果要仅使用流体容器对应用程序数据进行建模,则当容器损坏时,通信“链接”实际上就中断了。 类似的真实示例可能是视频通话,其中原作者与参与者共享了链接,并且该链接不再有效。 考虑到这一观点,一种选择是将恢复权限限制为原始作者,并让他们在恢复原始容器的副本后,以与共享原始链接相同的方式共享新的容器链接。

或者,如果你只对暂时性数据使用流体框架,则始终可使用自己的真实数据源和支持服务来管理更自主的恢复工作流。 例如,多个客户端可能会启动恢复过程,直到应用有了第一个恢复的副本。 然后,应用可以通知所有参与的客户端转换到新容器。 这很有用,因为任何当前活动的客户端都可以解除对参与组的阻止以继续进行协作。 这里需要考虑的一个因素是冗余所产生的成本。