自动缩放中的回摆

本文介绍自动缩放中的回摆以及如何避免这种情况。

回摆是指导致一系列相反缩放事件的循环状态。 当一个缩放事件触发相反的缩放事件时,就会发生回摆。

自动缩放会评估挂起的横向缩减操作以确定它是否会导致回摆。 在可能发生回摆的情况下,自动缩放可能会跳过缩放操作并在下次运行时重新评估,或者自动缩放可能按照小于指定的资源实例数量进行缩放。 每当自动缩放引擎运行时(每隔 30 到 60 秒运行一次,具体取决于资源类型),都会执行自动缩放评估过程。

为确保资源足够,不会针对横向扩展事件检查潜在的回摆。 自动缩放只会推迟横向缩减事件以避免回摆。

例如,让我们假设规则如下:

  • 当平均 CPU 使用率超过 50% 时,通过增加 1 个实例来横向扩展。
  • 当平均 CPU 使用率低于 30% 时,通过将实例计数减少 1 个来横向缩减。

在下表中的 T0 处,当使用率为 56% 时,将触发横向扩展操作,导致 2 个实例的 CPU 使用率为 56%。 这样可以得出,规模集的平均使用率为 28%。 由于 28% 小于横向缩减阈值,自动缩放应重新缩减。 横向缩减会使规模集恢复为 56% 的 CPU 使用率,这会触发横向扩展操作。

时间 实例计数 CPU 使用率 每个实例的 CPU 使用率 缩放事件 最终实例计数
T0 1 56% 56% 向外扩展 2
T1 2 56% 28% 缩小 1
T2 1 56% 56% 向外扩展 2
T3 2 56% 28% 缩小 1

如果不加以控制,将会持续发生一系列缩放事件。 但是,在这种情况下,自动缩放引擎将在 T1 处推迟横向缩减事件,并在下一次运行自动缩放期间重新评估。 仅当平均 CPU 使用率低于 30% 时,才发生横向缩减。

回摆通常由以下原因造成:

  • 阈值之间的余量很小或没有余量
  • 缩放程度超过一个实例
  • 使用不同的指标进行缩放

阈值之间的余量很小或没有余量

为了避免回摆,请在缩放阈值之间保持足够的余量。

例如,以下规则中的阈值之间没有余量,因此会导致回摆。

  • 当线程计数 >=600 时横向扩展
  • 当线程计数 < 600 时横向缩减

显示自动缩放规则的屏幕截图,当线程计数大于或等于 600 时,这些规则将执行横向扩展;当线程计数小于 600 时,将执行横向缩减。

下表显示了这些自动缩放规则的潜在结果:

时间 实例计数 Thread count 每个实例的线程计数 缩放事件 最终实例计数
T0 2 1250 625 向外扩展 3
T1 3 1250 417 缩小 2
  • 在时间 T0 处,有两个实例处理 1250 个线程,即每个实例处理 625 个线程。 自动缩放将横向扩展到三个实例。
  • 在横向扩展之后,在 T1 处,同样有 1250 个线程,但有三个实例,每个实例只处理 417 个线程。 触发横向缩减事件。
  • 在横向缩减之前,自动缩放会评估在发生横向缩减事件时会出现什么情况。 在此示例中,1250/2 = 625,即每个实例处理 625 个线程。 自动缩放在横向缩减后必须立即重新横向扩展。 如果再次横向扩展,该过程将会重复,从而导致回摆循环。
  • 为避免这种情况,自动缩放不会横向缩减。 自动缩放跳过当前缩放事件并在下一个执行周期重新评估规则。

在这种情况下,自动缩放看似未起作用,因为没有发生缩放事件。 检查自动缩放设置页上的“运行历史记录”选项卡,查看是否发生了任何回摆。

显示自动缩放运行历史记录选项卡的屏幕截图,其中包含显示回摆的记录。

在阈值之间设置足够的余量可以避免上述情况。 例如,

  • 当线程计数 >=600 时横向扩展
  • 当线程计数 < 400 时横向缩减

显示自动缩放规则的屏幕截图,当线程计数大于或等于 600 时,这些规则将执行横向扩展;当线程计数小于 400 时,将执行横向缩减。

如果横向缩减线程计数为 400,则总线程计数必须降至 1200 以下才会发生缩放事件。 请参阅下表。

时间 实例计数 Thread count 每个实例的线程计数 缩放事件 最终实例计数
T0 2 1250 625 向外扩展 3
T1 3 1250 417 无缩放事件 3
T2 3 1180 394 横向缩减 2
T3 3 1180 590 无缩放事件 2

缩放程度超过一个实例

为了避免在横向缩减或横向缩减程度超过一个实例时出现回摆,自动缩放可能会按照规则中指定的实例数量进行缩放。

例如,以下规则可能会导致回摆:

  • 当每个实例的请求计数 >=200 时按数量 20 横向扩展。
  • 或者,当每个实例的 CPU > 70% 时。
  • 当每个实例的请求计数 <=50 时按数量 10 横向缩减。

显示自动缩放默认缩放条件的屏幕截图,其中包含为示例配置的规则。

下表显示了这些自动缩放规则的潜在结果:

时间 实例数 CPU 请求计数 缩放事件 最终实例 注释
T0 30 65% 3000 个,即每个实例 100 个。 无缩放事件 30
T1 30 65 1500 按 3 个实例横向缩减 27 按数量 10 横向缩减会导致估算的 CPU 上升到 70% 以上,从而导致发生横向扩展事件。

在时间 T0 处,应用正在运行 30 个实例,请求总数为 3000,每个实例的 CPU 使用率为 65%。

在 T1 处,当请求计数下降到 1500 个请求或每个实例 50 个请求时,自动缩放将尝试按 10 个实例横向缩减到 20 个。 但是,自动缩放估计 20 个实例的 CPU 负载将超过 70%,从而导致发生横向扩展事件。

为避免回摆,自动缩放引擎会估计实例计数超过 20 时的 CPU 使用率,直到确定所有指标都在定义的阈值范围的实例计数:

  • 使 CPU 保持低于 70%。
  • 使每个实例的请求数保持在 50 以上。
  • 将实例数减少至 30 以下。

在这种情况下,自动缩放可能会按数量 3 横向缩减,即从 30 个缩减至 27 个实例,以满足规则,尽管规则指定的递减量为 10。 会将一条日志消息写入活动日志,其说明中包含“实例计数更新时将发生纵向缩减以避免回摆”

如果自动缩放找不到合适数量的实例,它会跳过横向缩减事件并在下一个周期重新评估。

注意

如果自动缩放引擎检测到由于缩放到目标实例数而可能发生回摆,则它还会尝试缩放到当前计数和目标计数之间的较低实例数。 如果在该范围内未发生摆动,则自动缩放会继续新目标的缩放操作。

日志文件

使用以下查询在活动日志中查找回摆:

// Activity log, CategoryValue: Autoscale
// Lists latest Autoscale operations from the activity log, with OperationNameValue =="Microsoft.Insights/AutoscaleSettings/Flapping/Action
AzureActivity
|where CategoryValue =="Autoscale" and OperationNameValue =="Microsoft.Insights/AutoscaleSettings/Flapping/Action"
|sort by TimeGenerated desc 

下面是回摆的活动日志记录示例:

显示回摆事件的日志记录的屏幕截图。

{
"eventCategory": "Autoscale",
"eventName": "FlappingOccurred",
"operationId": "1111bbbb-22cc-dddd-ee33-ffffff444444",
"eventProperties": 
    "{"Description":"Scale down will occur with updated instance count to avoid flapping. 
     Resource: '/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourcegroups/ed-rg-001/providers/Microsoft.Web/serverFarms/ScaleableAppServicePlan'.
     Current instance count: '6', 
     Intended new instance count: '1'.
     Actual new instance count: '4'",
    "ResourceName":"/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourcegroups/rg-001/providers/Microsoft.Web/serverFarms/ScaleableAppServicePlan",
    "OldInstancesCount":6,
    "NewInstancesCount":4,
    "ActiveAutoscaleProfile":{"Name":"Auto created scale condition",
    "Capacity":{"Minimum":"1","Maximum":"30","Default":"1"},
    "Rules":[{"MetricTrigger":{"Name":"Requests","Namespace":"microsoft.web/sites","Resource":"/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/rg-001/providers/Microsoft.Web/sites/ScaleableWebApp1","ResourceLocation":"China North","TimeGrain":"PT1M","Statistic":"Average","TimeWindow":"PT1M","TimeAggregation":"Maximum","Operator":"GreaterThanOrEqual","Threshold":3.0,"Source":"/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/ed-rg-001/providers/Microsoft.Web/sites/ScaleableWebApp1","MetricType":"MDM","Dimensions":[],"DividePerInstance":true},"ScaleAction":{"Direction":"Increase","Type":"ChangeCount","Value":"10","Cooldown":"PT1M"}},{"MetricTrigger":{"Name":"Requests","Namespace":"microsoft.web/sites","Resource":"/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/rg-001/providers/Microsoft.Web/sites/ScaleableWebApp1","ResourceLocation":"China North","TimeGrain":"PT1M","Statistic":"Max","TimeWindow":"PT1M","TimeAggregation":"Maximum","Operator":"LessThan","Threshold":3.0,"Source":"/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/ed-rg-001/providers/Microsoft.Web/sites/ScaleableWebApp1","MetricType":"MDM","Dimensions":[],"DividePerInstance":true},"ScaleAction":{"Direction":"Decrease","Type":"ChangeCount","Value":"5","Cooldown":"PT1M"}}]}}",
"eventDataId": "dddd3333-ee44-5555-66ff-777777aaaaaa",
"eventSubmissionTimestamp": "2022-09-13T07:20:41.1589076Z",
"resource": "scaleableappserviceplan",
"resourceGroup": "RG-001",
"resourceProviderValue": "MICROSOFT.WEB",
"subscriptionId": "aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e",
"activityStatusValue": "Succeeded"
}

后续步骤

若要了解有关自动缩放的详细信息,请参阅以下资源: