Azure Service Fabric 可靠集合和内存

Posted

技术标签:

【中文标题】Azure Service Fabric 可靠集合和内存【英文标题】:Azure Service Fabric reliable collections and memory 【发布时间】:2016-08-09 15:35:13 【问题描述】:

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

    如何计算我的可靠收藏可以容纳多少?

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

【问题讨论】:

azure.microsoft.com/en-us/documentation/articles/… 有一个线索“实际上今天你被绑定到盒子上的内存量” 问题 1 - “他们最多可以容纳多少”? @masnider 是的,归根结底。 【参考方案1】:

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

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

请注意,“可用内存”是机器上运行的其他代码(包括操作系统)留下的任何内容。在上面的示例中,尽管您没有在所有节点上运行 - 您只能获得其中的 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 的群集资源管理的其余部分将提供帮助的地方,因为我们可以了解不同副本的消耗并将它们有效地打包到群集中以利用可用空间。与集合中的状态相关的资源消耗的自动报告在我们的雷达上,也是我们想做的事情,所以在未来,这将是自动的,但今天你必须自己报告这个消耗。

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 位引用。这将为您提供一个较低的起点。 存储开销。您存储在集合中的每个对象都会带来一些存储该对象的开销。在依赖于集合和当前运行中的操作(复制、枚举、更新等)的可靠集合中,此开销可以在集合中存储的每个项目(行)100 到大约 700 个字节之间。也知道我们一直在寻找减少我们引入的开销的方法。

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

我知道这是一个很长的答案,但我希望它对您有所帮助且完整。

【讨论】:

感谢您的详尽回答。对于从字典中清理过时的数据,您有什么建议? 您必须弄清楚“陈旧”在该数据和服务的上下文中的含义,然后将其删除(通常也将其归档到其他地方,例如 DocDB)。通常这是其他一些字典,它将时间戳(数据被修改的时间)作为键,并将字典中数据的键作为值。然后每隔一段时间运行一个任务并将数据保存到冷库,然后删除原始字典中的数据。标记和扫描是一个很好的模式。在决定应该删除某些东西并让它再次变得新鲜的竞争条件下要小心。 HTH @masnider ReliableQueue 和 ReliableConcurrentQueue 使用 RAM 和磁盘的方式是否与其他 Reliable Collections 相同?我希望随着 ReliableConcurrentQueue 的增长(因为它不能足够快地消耗),StateManager 会跳过写入 RAM 并直接写入磁盘?如果不是这种情况,我想由我来手工制作“标记和扫描”,但用于队列而不是集合,然后当队列深度下降时,基本上将这些消息反转回队列? 是的,你必须这样做。所有集合都以相同的方式使用资源。它们都写入内存记录和磁盘。 这个答案在 2018 年 4 月仍然有效还是有什么变化?如果我考虑前。三个节点,每个副本,每个 16GB 内存和 50GB 磁盘 - 我是否应该考虑所有可靠集合的最大容量为 16GB 减去系统开销?

以上是关于Azure Service Fabric 可靠集合和内存的主要内容,如果未能解决你的问题,请参考以下文章

Azure Service Fabric 可靠参与者与可靠服务

Azure上的Service Fabric Cluster创建失败,错误代码为“VMInstanceCountAllowsBetterReliabilityLevel”

Service Fabric 微服务与 Azure 云服务/Web 应用程序集合的优势

Azure Service Fabric - 外部状态管理器

Azure Service Fabric 与 Azure Service Fabric Mesh

aZURE Service Fabric