如何测量 Service Fabric 中分区级别的资源使用情况?
How to measure resource usage on partitionlevel in Service Fabric?
借助 Service Fabric,我们获得了创建自定义指标和容量的工具。通过这种方式,我们都可以制作自己的资源模型,供资源平衡器用于在 运行 时间执行。我想监控和使用物理资源,例如:内存、cpu 和磁盘使用情况。只要我们继续使用默认负载,这就可以正常工作。
但是 service/actor 的负载不是静态的,所以我想使用内置的动态负载报告。这是我 运行 遇到的问题,ReportLoad 在分区级别上工作。但是分区都在节点上的同一个进程中。我发现所有监控物理资源的方法都是以进程为最小计量单位,比如PerformanceCounter。如果使用此值,则可能有数百个分区报告相同的负载和一个不代表该分区的负载。
所以问题是:如何在分区级别衡量资源使用情况?
不仅服务实例和副本托管在同一个进程中,而且在 .NET 中它们还默认共享一个线程池!每次您创建一个新的服务实例时,平台实际上只是在宿主进程中创建您的服务实例 class(派生自 StatefulService 或 StatelessService 的实例)。这很棒,因为它快速、便宜,而且您可以将大量服务打包到单个主机进程中,然后打包到集群中的每个 VM 或机器上。
但这也意味着资源是共享的,那么你怎么知道每个分区的每个副本使用了多少?
答案是您报告虚拟资源 而非物理资源的负载。这个想法是,作为服务作者,您可以跟踪有关您的服务的一些度量,并根据该信息制定指标。下面是一个基于物理资源的虚拟资源的简单示例:
假设您有一个网络服务。您 运行 对您的 Web 服务进行负载测试,并确定它在各种硬件配置文件上每秒可以处理的最大请求数(使用 Azure VM 大小和完全虚构的数字作为示例):
- A2:500 转/秒
- D2: 1000 转/秒
- D4:1500 转/秒
现在,当您创建集群时,您可以根据您使用的硬件配置文件相应地设置您的容量。因此,如果您有一个 D2 集群,每个节点将定义 1000 RPS 的容量。
然后您的 Web 服务的每个实例(或副本,如果有状态)报告一个平均 RPS 值。这是一个 虚拟资源 ,您可以根据 instance/replica 轻松计算。它对应于某些硬件配置文件,即使您没有直接报告 CPU、网络、内存等。您可以将此应用于任何您可以衡量的服务,例如队列长度、并发用户数等。
如果您不想定义与每秒请求数一样具体的容量,您可以采用更通用的方法,为常见资源(如内存或磁盘使用)定义物理容量。但您在这里真正要做的是为您的服务定义 可用 内存和磁盘,而不是总可用内存和磁盘。在您的服务中,您可以跟踪每个 instance/replica 使用的容量。但这不是总值,它只是你所知道的东西。因此,例如,如果您要跟踪存储在内存中的数据,它不一定包括 运行时间开销、临时堆分配等。
我在 Reliable Collection wrapper 中有一个这种方法的例子,我写的它通过计算字节数严格地根据您存储的数据量报告负载指标:https://github.com/vturecek/metric-reliable-collections。它不报告总内存使用情况,因此您必须合理估计您需要多少开销并相应地定义您的容量,但同时不报告临时堆分配和其他临时内存使用情况,指标报告的结果应该更平滑并且更能代表您正在存储的实际数据(例如,您不一定要仅仅因为 .NET GC 还没有 运行 就重新平衡集群) .
借助 Service Fabric,我们获得了创建自定义指标和容量的工具。通过这种方式,我们都可以制作自己的资源模型,供资源平衡器用于在 运行 时间执行。我想监控和使用物理资源,例如:内存、cpu 和磁盘使用情况。只要我们继续使用默认负载,这就可以正常工作。
但是 service/actor 的负载不是静态的,所以我想使用内置的动态负载报告。这是我 运行 遇到的问题,ReportLoad 在分区级别上工作。但是分区都在节点上的同一个进程中。我发现所有监控物理资源的方法都是以进程为最小计量单位,比如PerformanceCounter。如果使用此值,则可能有数百个分区报告相同的负载和一个不代表该分区的负载。
所以问题是:如何在分区级别衡量资源使用情况?
不仅服务实例和副本托管在同一个进程中,而且在 .NET 中它们还默认共享一个线程池!每次您创建一个新的服务实例时,平台实际上只是在宿主进程中创建您的服务实例 class(派生自 StatefulService 或 StatelessService 的实例)。这很棒,因为它快速、便宜,而且您可以将大量服务打包到单个主机进程中,然后打包到集群中的每个 VM 或机器上。
但这也意味着资源是共享的,那么你怎么知道每个分区的每个副本使用了多少?
答案是您报告虚拟资源 而非物理资源的负载。这个想法是,作为服务作者,您可以跟踪有关您的服务的一些度量,并根据该信息制定指标。下面是一个基于物理资源的虚拟资源的简单示例:
假设您有一个网络服务。您 运行 对您的 Web 服务进行负载测试,并确定它在各种硬件配置文件上每秒可以处理的最大请求数(使用 Azure VM 大小和完全虚构的数字作为示例):
- A2:500 转/秒
- D2: 1000 转/秒
- D4:1500 转/秒
现在,当您创建集群时,您可以根据您使用的硬件配置文件相应地设置您的容量。因此,如果您有一个 D2 集群,每个节点将定义 1000 RPS 的容量。
然后您的 Web 服务的每个实例(或副本,如果有状态)报告一个平均 RPS 值。这是一个 虚拟资源 ,您可以根据 instance/replica 轻松计算。它对应于某些硬件配置文件,即使您没有直接报告 CPU、网络、内存等。您可以将此应用于任何您可以衡量的服务,例如队列长度、并发用户数等。
如果您不想定义与每秒请求数一样具体的容量,您可以采用更通用的方法,为常见资源(如内存或磁盘使用)定义物理容量。但您在这里真正要做的是为您的服务定义 可用 内存和磁盘,而不是总可用内存和磁盘。在您的服务中,您可以跟踪每个 instance/replica 使用的容量。但这不是总值,它只是你所知道的东西。因此,例如,如果您要跟踪存储在内存中的数据,它不一定包括 运行时间开销、临时堆分配等。
我在 Reliable Collection wrapper 中有一个这种方法的例子,我写的它通过计算字节数严格地根据您存储的数据量报告负载指标:https://github.com/vturecek/metric-reliable-collections。它不报告总内存使用情况,因此您必须合理估计您需要多少开销并相应地定义您的容量,但同时不报告临时堆分配和其他临时内存使用情况,指标报告的结果应该更平滑并且更能代表您正在存储的实际数据(例如,您不一定要仅仅因为 .NET GC 还没有 运行 就重新平衡集群) .