100%cpu使用率(最大值)下CpuShares的服务矩阵代码包值

时间:2018-09-20 05:59:28

标签: azure-service-fabric service-fabric-stateless

我有2个服务结构应用程序(sln)和3个服务(3个代码包)。我想以最大CPU百分比的40%20%20%分配这些值,而不管内核如何,即,对CPU内核数没有限制(当前计算机为4内核逻辑)。根据上面的内容/博客,如果我指定CpuShares = 512,CpuShares = 256和CpuShares = 256,那么它将占用40%,20%,20%的最大CPU。但是,事实并非如此,它仅允许相应服务的最大CPU使用率的5%,2%和2%。通过阅读这篇文章(https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-resource-governance)  我以为1024是CpuShares的默认值(最大值),经过大量的尝试和错误后,如果我们应用的值大于此值,我最终会得出10,000的CpuShares值,我们会在服务浏览器中看到错误消息,说CpuShare的参数无效。 因此,考虑10,000 =允许100%CPU使用率。在测试中,我已将上述CPU份额值修改为CpuShares = 4000,CpuShares = 2000和CpuShares = 2000,我可以看到最大CPU使用率,其中40%20%20%(不是精确的5%差异)。所以问题是我在任何文档中都找不到10,000 = 100%CPU使用率值。因此,我想确认这是否正确,如果不正确,该如何限制服务或代码包的特定百分比。请对此提供帮助

1 个答案:

答案 0 :(得分:0)

关于SF中服务资源管理的一个常见误解是,它是服务的 资源保留和隔离容量 ,就像在docker容器上一样,这是不正确的。

这些度量标准是软限制,用于保持群集中服务的平衡,并不意味着它们专门为您的服务保留,其他服务可以保留,并且如果未设置限制,则将消耗这些资源。

  

要使资源限制强制生效,服务包中的所有代码包都应指定内存限制。

度量标准是用于在集群中找到适当的服务平衡并将服务放置在具有可用资源的节点中的度量,因此,假设您拥有服务A,B和C,并且每个服务都有特定数量的资源需求,比如说内存,这是一个易于理解的值,A = 1000MB,B = 512MB,C = 512MB,并且一个节点有2GB的内存,可以将它们放置在同一节点中,因此假设服务C在服务时需要1000MB需要激活C,它将避免激活A和B的同一节点,因为即使这些服务没有消耗所有请求的资源,它也没有能力在其中运行,并且将选择另一个节点。 / p>

来自docs

  

Service Fabric运行时当前不提供以下内容的保留:   资源。打开进程或容器时,运行时设置   在创建时定义的负载的资源限制。   此外,运行时拒绝打开新的服务包   超出资源时可用。

关于股份的主要问题:

同一文档描述共享是在该节点上激活的所有代码包之间分配给服务包的预留CPU核心的一部分,如果您为每个代码包定义份额,则它们的总和为总计,每个人将获得这些股份的一部分。

如何控制这些股份?

  

请记住,以下内容未在任何地方得到正式记录,在某些方面,我可能是错的,我从源代码中获得了此信息,并且我可能错过了一些细节

假定激活了带有代码包A和B的服务包,并拆分了以下份额:

  • 代码包A(CP.A)= 1500股
  • 代码包B(CP.B)= 500股

SF将:

  • 确定为服务包保留的CPU核心容量:
    • 容量将是CPU核心保留容量(%)/总可用容量
    • 在4核cpu上:1个cpu核保留= 25%
  • 从代码包中获取所有份额并求和它们的值,以确定多少份额应代表100%的保留容量(25%)
    • 1500 + 500 = 2000总份额
    • CP.A应该获得4分之三的分数
    • CP.B应该收到四分之一的分数
  • 将份额转换为CPU作业周期(请参阅下面的原因)
    • CP.A应该收到10,000的3/4-> 7500个周期
    • CP.B应该接收10,000的1/4-> 2500个周期
  • 将保留周期数乘以保留的cpu内核数量
    • CP.A应该收到7500个周期的25%
    • CP.B应该获得2500个周期的25%

这些限制受Job Objects的约束,当一个流程(代码包)被激活时,只要该流程消耗的周期多于作业中设置的限制,它就会被分配给设置了这些限制的作业,线程被抢占,而另一个进程线程被调度在内核中。在代码中,他们建议使用10000 represents all available cores,但正确的是number of processor cycles that the threads in a job object can use during each scheduling interval。在一个作业中,每个作业计划的间隔为10000个周期,一个线程在此作业中进行了调度,将消耗此计划的x个周期,并且如果保留4个内核,则只会消耗10000个周期。

确切的逻辑在这段代码中:

    double shares = fractionOfSp * Constants::JobObjectCpuCyclesNumber;
    shares = shares * (numCoresAllocated / max(numAvailableCores_, systemCpuCores_));
    rg.CpuShares = static_cast<uint>(shares);

    //fractionOfSp -> Fraction of a Service Package
    //   - A service package represents 100% (Like a Pizza) of reserved core capacity
    //   - Each Code Package will have one or more fraction (A slice of the pizza)
    //Constants::JobObjectCpuCyclesNumber -> is a constant for 10000 cycles
    //numCoresAllocated -> How many cores you assigned to a service package

一些技巧:

  • 保留的核心数量也会影响结果,您必须保留至少0.01%的核心才能生效。
  • 份额基于保留给Service Package的CPU内核,而不是节点中所有可用的CPU,如果您的节点有4个内核,则为ServicePackage保留1个内核,这意味着您将在每个节点之间共享25%的节点容量代码包。
  • 如果某些代码包的共享为零或没有共享,则即使您指定了任何值,所有代码包也将具有相同的分数。
  • 在linux上,它使用CpuQuota
  • 作业的最大循环数为10k

如果您需要更多信息,请查看源代码here

PS:计算所有这些数字时我有些头晕,我稍后可能会再次审查!