为什么我的Service Fabric演员使用的磁盘空间超出预期?

时间:2017-08-29 12:11:02

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

我试图了解为什么我们的actor服务使用的磁盘空间超出预期。我们的服务目前包含分布在10个分区的大约80,000名演员。每个演员都存储大约150Kb的州。

查看我们集群中的一个(十分之一)节点,我希望看到:

  • 用于大约3个分区的磁盘空间(一个作为主分区,两个作为辅助分区)
    • 这是预期的
  • 深入到一个分区文件夹,我希望只看到一个副本ID
    • 与预期不符:
      • 我看到了预期的一个(与Service Fabric Explorer中节点部分下列出的副本匹配的那个)。副本标识前缀为R_
      • 在同一个分区文件夹中,我看到3个其他文件夹,副本ID以前缀S_开头。这些副本ID与“应用程序”节点下的Service Fabric Explorer中列出的任何值都不匹配。
  • 查看以R_开头的副本文件夹,我希望该文件夹包含的内容不超过8000个大小,每个大约150 Kb,大约1.14 Gb的数据。
    • 与预期不符:
      • 该文件夹包含文件ActorStateStore,其大小为5.66Gb

我想要了解的另一件事是:

  • 我们的应用程序版本1没有清理未使用的actor。正如您所料,我们看到每个节点上的磁盘使用量都在稳步增长。
  • 我们的应用程序的第2版开始删除未使用的actor。由于这个新代码将超过一半的活跃参与者,我在部署后的预期是整体使用的磁盘大小将显着下降。
    • 没有发生,增长停止但使用量没有缩小。

所以我的问题是:

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

1 个答案:

答案 0 :(得分:1)

  

深入到一个分区文件夹,我希望能看到   一个副本id

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

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

    一个。例如,假设某个副本处于某个副本的节点出现故障,并且该节点的停留时间比该服务的ReplicaRestartWaitDuration长。发生这种情况时,SF会构建一个替换副本,以使您返回到TargetReplicaSetSize

    湾让我们说,一旦构建了该副本,失败的节点就会回来。

    ℃。如果我们仍然在该副本的StandbyReplicaKeepDuration内,那么SF将把它留在磁盘上。如果在此期间发生另一次失败,SF通常会(取决于Cluster Resource Manager设置,此节点是否为有效目标等)。选择此部分副本并从驱动器上剩余的内容重建替换。

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

  3.   

    我希望该文件夹包含的内容不会超过   8000名演员每人大约150 Kb,因此大约1.14 Gb的数据。   不像预期的那样:该文件夹包含一个文件ActorStateStore及其文件   大小是5.66Gb

    这有点令人费解。让我们回到我们期望在给定节点上的数量。你说你有80K演员。我认为你有TargetReplicaSetSize的3,所以它更像240K演员。每个actor都是~150K的状态,因此群集的状态为~34 GB。然后,每个节点我们期望3.4 GB的状态。 (我认为你原来的估计忘了复制。如果你的TargetReplicaSetSize实际上是{1},那么请告诉我,我们可以重新计算。)

    ~3.4gb更接近您对~5.7gb的观察,但不够接近。其他一些要记住的事情:

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

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

      

    增长停止了,但使用量没有减少。

    这可能只是在数据存储级别分配的空间,不会被重新打包/回收。我们需要了解实际上仍占据空间的内容,以了解情况。其中一些取决于实际的持久性存储(ESE / KVS与基于字典的状态提供程序)。作为升级的一部分,你的生成发生了变化的ActorIds也有可能,因此新代码无法引用" old" ActorIds(但感觉不太可能)。