Azure Service Fabric 可靠的集合和内存

Azure Service Fabric reliable collections and memory

假设我运行在 5 个 D1 class(1 个核心、3.5GB RAM、50GB SSD)VM 上建立一个 Service Fabric 集群。并且我 运行 在这个集群上提供了 2 个可靠的服务,一个是无状态的,一个是有状态的。假设副本目标是 3。

  1. 如何计算我可靠的藏品能装多少?

  2. 假设我添加了一项或多项有状态服务。因为我真的不知道框架是如何分发服务的,所以我需要采取最保守的方法并假设一个节点可能 运行 我在单个节点上的所有有状态服务并且它们的累积内存需要低于一台机器上可用的 RAM?

TLDR - 估计集群的预期容量部分是艺术,部分是科学。您可能会得到一个很好的下限,您可以将其推高,但在大多数情况下,部署 运行 它们并在您的工作负载条件下收集数据是回答这个问题的最佳方式。

1) 通常,给定机器上的集合受节点上可用内存量或可用磁盘量 space 的限制,以较低者为准。今天,我们将集合中的所有数据保存在内存中,并将其持久化到磁盘。因此,集群中的集合可以容纳的最大数量通常是(集群中的可用内存量)/(目标副本集大小)。

请注意,"Available Memory" 是机器上其他代码 运行 遗留下来的任何内容,包括 OS。在上面的示例中,虽然您没有 运行 跨越所有节点 - 但您只能获得其中的 3 个。因此,(不切实际地)假设这些其他因素的开销为 0,您可以期望能够在 运行 其所在节点上的内存不足之前将大约 3.5 GB 的数据放入该有状态服务副本中 运行。集群中仍有 2 个节点为空。

再举个例子。假设它与上面的示例大致相同,除了在这种情况下您设置要分区的有状态服务。假设您选择的分区数为 5。因此现在在每个节点上,您都有一个主副本和 2 个来自其他分区的辅助副本。在这种情况下,每个分区最多只能保存大约 1.16 GB 的状态,但现在总体而言,您可以将 5.83 GB 的状态打包到集群中(因为现在可以充分利用所有节点)。顺便说一下,为了证明数学是可行的,即(每个节点 3.5 GB 内存 * 集群中的 5 个节点)[17.5] /(目标副本集大小 3)= 5.83。

在所有这些示例中,我们还假设所有分区和所有副本的内存消耗是相同的。很多时候事实并非如此(至少暂时如此)- 某些分区最终可能会有或多或少的工作要做,因此资源消耗不均匀。我们还假设次级始终与初级相同。在状态数量的情况下,假设这些将相当均匀地跟踪可能是公平的,尽管对于其他资源消耗它可能不会(只是要记住的一点)。在消费不均匀的情况下,这确实是 Service Fabric 的集群资源管理的其余部分可以提供帮助的地方,因为我们可以了解不同副本的消费情况并将它们有效地打包到集群中以利用可用 space.自动报告集合中与状态相关的资源消耗在我们的雷达上,也是我们想要做的事情,所以在未来,这将是自动的,但今天你必须自己报告这种消耗。

2) 默认情况下,我们会根据默认指标来平衡服务(更多关于指标的信息是here)。所以默认情况下,这两个不同服务的不同副本最终可能会出现在机器上,但在你的例子中,你最终会得到 4 个节点,其中 1 个副本来自一个服务,然后 1 个节点有来自两个服务的两个副本不同的服务。这意味着每个服务(根据您的示例,每个服务有 1 个分区)在每个服务中只能消耗 1.75 GB 的内存,而集群中的内存总量为 3.5 GB。这再次小于集群的总可用内存,因为您没有使用节点的某些部分。

请注意,这是最大可能消耗量,并且假定服务本身之外没有消耗量。以此作为您的最大值是不可取的。您会出于多种原因想要减少它,但最实际的原因是确保在出现升级和故障时集群中有足够的可用容量。例如,假设您有 5 个升级域和 5 个故障域。现在假设当您在升级域中进行升级时,故障域的节点价值发生故障。这意味着(略低于)40% 的集群容量随时可能消失,您可能希望在剩余节点上留下足够的空间以继续运行。这意味着,如果您的集群以前可以容纳 5.83 GB 的状态(根据我们之前的计算),实际上您可能不想在其中放置超过 3.5 GB 的状态,因为如果有更多的状态,服务可能无法恢复到 100% 健康(另请注意,我们不会立即构建替换副本,因此在您 运行 进入这种情况之前,节点必须关闭您的 ReplicaRestartWaitDuration)。 this article.

中涵盖了有关指标、容量、缓冲容量(您可以使用它来确保在节点上为故障情况留出空间)以及故障和升级域的更多信息。

还有一些其他因素实际上会限制您能够存储的状态量。您需要做几件事:

  • 估计数据的大小。您可以通过计算对象包含的每个字段的大小来预先合理估计数据的大小。请务必考虑 64 位引用。这将为您提供下限起点。
  • 存储开销。您存储在集合中的每个对象都会有一些存储该对象的开销。在依赖于集合和当前正在进行的操作(复制、枚举、更新等)的可靠集合中,这种开销可以 运行ge 从集合中存储的每个项目(行)100 到大约 700 字节不等。还要知道我们一直在寻找减少我们引入的开销的方法。

我们还强烈建议 运行 您在一段时间内使用您的服务,并通过性能计数器测量实际资源消耗。模拟某种真实的工作负载,然后测量您关心的指标的实际使用情况,这对您很有帮助。我们特别推荐这样做的原因是,您将能够从诸如您的对象最终放置在哪个 CLR 对象堆中、GC 的频率 运行、是否存在泄漏或类似这样的其他事情中看到消耗情况将影响您实际可以使用的内存量。

我知道这是一个很长的答案,但我希望你觉得它有用且完整。