为什么我的 Service Fabric 参与者使用的磁盘 space 比预期的多?

Why are my Service Fabric actors using more disk space than expected?

我想了解为什么我们的演员服务使用的磁盘 space 比预期的多。我们的服务目前包含分布在 10 个分区中的大约 80,000 个参与者。每个 actor 存储大约 150Kb 的状态。

查看集群中的一个(共 10 个)节点,我希望看到:

我想了解的另一件事如下:

所以我的问题是:

  1. 我的预期是否正确?
  2. 什么可以解释我的观察结果?

Drilling down into one partition folder, I would expect to see just one replica id

如果事情已经 运行 一段时间了,我希望看到不止一个。这是因为两件事:

  1. Service Fabric 至少在 ReplicaRestartWaitDuration 内保留节点上发生故障的副本的信息。这样一来,如果可以进行本地恢复,节点上仍然有必要的信息。例如,如果副本刚刚发生故障并且无法彻底删除,则此类文件可能会累积。如果有人“ForceRemoved”个人副本,它们也可以存在,因为这明确地跳过了干净关闭。这就是为什么我们通常不建议在生产环境中使用此命令的部分原因。
  2. 还有一个称为“UserStandbyReplicaKeepDuration”的设置,它控制 SF 将不需要的旧副本保留多长时间现在,以防以后需要它们(因为从部分状态重建通常比从完整状态重建更便宜)。

    一个。例如,假设某个节点上的某个副本发生故障并且停机时间超过该服务的 ReplicaRestartWaitDuration。发生这种情况时,SF 会构建一个替代副本,让您回到 TargetReplicaSetSize

    b。假设一旦构建了副本,失败的节点就会恢复。

    c。如果我们仍在该副本的 StandbyReplicaKeepDuration 内,则 SF 会将其保留在磁盘上。如果同时出现另一个故障,SF 通常会(取决于 Cluster Resource Manager 设置、此节点是否是有效目标等)选择此部分副本并从驱动器上剩余的内容重建替换。

    因此您可以看到过去的副本,其信息仍保存在驱动器上,但您通常不会看到比 UserStandbyReplicaKeepDuration(默认为一周)更早的任何内容。如果需要,您始终可以减少集群中的持续时间。

I would expect the folder to contain not much more than the size of 8000 actors taking up around 150 Kb each so around 1.14 Gb of data. Not as expected:The folder contains a file ActorStateStore and its size is 5.66Gb

这有点令人费解。让我们回到我们期望在给定节点上的东西的数量。你说你有 80K 演员。我假设您的 TargetReplicaSetSize 为 3,所以这实际上更像是 24 万名演员。每个 actor 有大约 150K 的状态,所以集群有大约 34 GB 的状态。那么我们期望每个节点有 3.4 GB 的状态。 (我认为您最初的估计忘记了复制。如果您的 TargetReplicaSetSize 实际上是 1,请告诉我,我们可以重新计算。)

~3.4gb 更接近你观察到的~5.7gb,但还不够接近。其他一些注意事项:

  • 序列化开销:actor 框架通常使用 NetDataContractSerializer 来序列化您的 actor 状态中的数据。你可能想测试看看这是否会导致你的 150K 状态增加 60%(这会带来很大的开销,但这并非闻所未闻)
  • "leftover" 位演员。如果您动态创建副本,请记住一件事,即在您告诉 SF 删除它们之前,它们不会被完全删除

    var serviceUri = ActorNameFormat.GetFabricServiceUri(typeof(IMyActor), actorAppName); var actorServiceProxy = ActorServiceProxy.Create(actorId.GetPartitionKey(), serviceUri); await actorServiceProxy.DeleteActorAsync(actorId, cancellationToken);

The growth stopped but the usage did not shrink.

这可能只是在未获得 repacked/reclaimed 的数据存储级别分配的 space。我们需要查看实际上仍在占用 space 的内容以了解情况。其中一些取决于实际的持久性存储(ESE/KVS 与基于字典的状态提供程序)。作为升级的一部分,您生成的 ActorId 也有可能以某种方式发生了变化,因此新代码无法引用 "old" ActorId(但这不太可能)。