乐趣区

AutoScaling-成本优化模式升级混合实例策略

伸缩组成本优化模式以成本为目标,始终创建最低价的实例,同时,通过多可用区,多实例规格分布,以此来提高服务稳定性。但是,对于成本优势最大化的竞价实例,伸缩组难以防范竞价实例大范围回收可能导致的服务雪崩,本次升级允许用户制定更详细的成本控制策略,在成本和稳定性之间进行调整和权衡。

成本优化模式简介

当您的伸缩配置选择了多实例规格,并想以最低的价格来使用同等规模的 ECS 实例配置时,您可以选择使用 成本优化策略  的伸缩组,来降低您的 ECS 实例使用成本;当您的伸缩配置选择的实例为抢占式实例时,您可能会遇到由于价格、库存等原因导致抢占式实例创建失败场景,从而导致扩容不及时,影响到业务,您也可以选择使用  成本优化策略 的伸缩组,在抢占式实例创建失败的时候自动为您尝试创建同规格的按量实例,来保证业务的稳定性。

从上述的描述,我们可以清晰的看到,成本优化模式的核心策略:

  1. 创建实例时,以单核 cpu 价格价格最低来选择创建实例的 InstanceType(实例规格),ZoneId(可用区)等配置信息。
  2. 竞价实例创建失败时,调整为创建按量实例,以保证业务连续性。

我们将上述的策略称为最低价策略(LowestPrice)。

关于成本优化模式更详细的信息,请查看 AutoScaling 推出成本优化模式。

成本优化模式升级

成本优化模式的升级策略主要针对竞价实例回收机制可能带来的业务雪崩情况。主要集中在以下两点:

  1. 混合实例配比。允许用户为成本优化伸缩组制定按量实例与竞价实例的混合策略。
  2. 竞价实例主动替换。在竞价实例释放前创建新实例,主动替换掉当前的竞价实例。

在下面的文章中,我们将原成本优化伸缩组称为普通成本优化伸缩组,将指定实例混合策略的成本优化伸缩组称为成本优化混合实例伸缩组。

参数详解

  • OnDemandBaseCapacity

伸缩组所需要的按量实例的最小个数,当伸缩组中按量实例个数小于该值时,将优先创建按量实例。

  • OnDemandPercentageAboveBaseCapacity

满足 OnDemandBaseCapacity 条件后,创建实例中按量实例所占的比例。

  • SpotInstancePools

SpotInstancePools 指定了最低价的多个实例规格,当创建竞价实例时,将在 SpotInstancePools 中进行均衡分布。

  • SpotInstanceRemedy

是否开启竞价实例的补偿机制。开启后在竞价实例被回收前 5 分钟左右,将主动替换掉当前竞价实例。

兼容性介绍

成本优化混合实例伸缩组与普通成本优化伸缩组在接口和功能方面是完全兼容的。当您不指定混合实例策略的相关参数时,您将创建出普通成本优化伸缩组。同时,对于成本优化混合实例伸缩组,通过合理的制定混合实例策略,能够具有与普通成本优化伸缩组完全相同的行为。下面举例说明:

  1. 假设普通成本优化伸缩组创建的全为按量实例。

此时,你创建的成本优化混合实例伸缩组只需要指定 OnDemandBaseCapacity=0, OnDemandPercentageAboveBaseCapacity=100,spotInstancePools=1,那么将拥有完全相同的行为。

  1. 假设普通成本优化伸缩组优先创建竞价实例。

此时,你创建的成本优化混合实例伸缩组只需要指定 OnDemandBaseCapacity=0, OnDemandPercentageAboveBaseCapacity=0,spotInstancePools=1,那么将拥有完全相同的行为。

扩缩容策略

成本优化混合实例伸缩组拥有一套相对独立的扩缩容策略,您在大多数情况下不需要关注实例的选择过程,如果您需要对伸缩组行为具有更详细的了解,本节中对扩缩容过程进行了详细的描述。

扩容策略

当指定了伸缩组的实例混合策略之后,伸缩组并非仅对新创建出来的实例按照混合比例进行创建,而是保证伸缩组整体的实例配比趋近目标配比。

  • 按量实例扩容策略

按量实例部分,采用了 LowestPrice 的创建方式,多实例规格与多可用区按照优先级方式依此进行选择,该部分与普通成本优化伸缩组保持一致。

  • 竞价实例扩容策略

竞价实例部分,采用了 LowestPrice 的创建方式,当配置多实例规格时,将根据 SpotInstancePools 配置,在最低价的多个实例规格之间平均分配,针对每一种实例规格,当无法成功创建时,按照价格顺序依次选取下一规格继续进行创建,当竞价实例全部不可创建,将退回到创建对应的按量实例。多可用区则按照优先级的方式依次进行选择。

下面,我们通过示例来描述成本优化混合实例伸缩组的扩容行为:

假设伸缩组组内按量实例个数为 3,竞价实例为 1 个 ecs.n1.tiny 规格实例,OnDemandBaseCapacity = 5,OnDemandPercentageAboveBaseCapacity = 40,SpotInstancePools = 2,伸缩组实例规格配置为:ecs.n1.tiny, ecs.n1.small,ecs.n1.medium(价格依此上升)。

扩容数量 按量实例分配情况 竞价实例分配情况
0 3 1(tiny)
1 4 1(tiny)
2 5 1(tiny)
3 6 1(tiny)
4 7 1(tiny)
5 7 1(tiny)1(small)
6 7 2(tiny)1(small)
7 8 2(tiny)1(small)
8 8 2(tiny)2(small)
缩容策略

成本优化混合实例伸缩组的释放策略不遵循伸缩组上指定的释放策略,为了保持实例伸缩组内实例的混合配比,将采用以下描述的实例释放策略。首先,将根据伸缩组实例混合策略,确定将要释放的按量实例与竞价实例的个数,我们将在保证足够数量的实例被释放的前提下,按照伸缩组整体趋近期望配比的方式确定释放按量实例和竞价实例的个数。当按量实例个数不足时,将释放更多的竞价实例;当竞价实例个数不足时,将改为释放按量实例。

  • 按量实例缩容策略

释放按量实例时,将按照以下条件选择可释放的实例:

  1. 优先释放价格高的实例;
  2. 价格相同时,按照伸缩组指定的释放策略选取合适数量的实例进行释放。
  • 竞价实例缩容策略

释放竞价实例时,将按照以下条件选择可释放的实例:

  1. 将首先释放不属于 spotInstancePools 中规格类型的实例,这部分实例的释放策略与上述按量实例的缩容策略相同;
  2. 如果还需要释放规格类型属于 spotInstancePools 的实例,将进一步选择释放所需要的实例,选择方式如下:

    1. 选择释放的实例将使得剩余实例的实例规格在 spotInstancePools 中趋于均衡分布;
    2. 相同规格的多个实例可供选择时,将按照伸缩组指定的释放策略选择释放的实例。

下面,同样我们通过简单的示例来描述成本优化混合实例伸缩组在缩容时的实例选择过程:

假设伸缩组组内按量实例个数为 8,竞价实例为 2 个 ecs.n1.tiny 规格实例,2 个 ecs.n1.small 规格实例,OnDemandBaseCapacity = 5,OnDemandPercentageAboveBaseCapacity = 40,SpotInstancePools = 2,伸缩组实例规格配置为:ecs.n1.tiny, ecs.n1.small,ecs.n1.medium(价格依此上升)。

缩容数量 按量实例分配情况 竞价实例分配情况
0 8 2(tiny)2(small)
1 8 2(tiny)1(small)
2 7 2(tiny)1(small)
3 7 1(tiny)1(small)
4 7 1(tiny)
5 6 1(tiny)
6 6 0
7 5 0
8 4 0

竞价实例补偿

竞价实例在系统回收之前五分钟左右将会发送系统回收消息,当您开启竞价实例主动替换功能之后,在系统发送竞价实例的回收消息之后,弹性伸缩将会为该竞价实例创建补偿任务,并在稍后通过创建新的竞价实例来替换即将释放的实例。我们将这一主动替换即将被回收的竞价实例的行为称为 竞价实例补偿

竞价实例补偿是保障业务连续性的辅助保障机制,该补偿机制具有以下特点,你需要对这些特点有充分的认识,以便您配置合理的成本优化伸缩组。

  1. 竞价实例补偿的时间窗口。在收到竞价实例系统回收消息后,将为对应的实例生成补偿任务,大约五分钟时间后实例将被回收,当实例被回收后,伸缩组内的对应实例将被健康检查机制清除伸缩组(大约 6 分钟)。竞价实例补偿任务的有效期为:补偿任务生成到健康检查将实例移除伸缩组之间。一旦错过补偿时间窗口,对应的补偿任务将会失效和清理,意味着对应实例错过补偿期。
  2. 有限的补偿能力。一次竞价实例的补偿过程分为新实例启动和旧实例释放两个过程,补偿任务执行过程中,伸缩组将处于锁定状态。由于暂时伸缩组不支持并行伸缩活动处理,因此,在有限的补偿时间窗口内,能够进行的补偿任务次数和实例数是有限的。由于竞价实例回收通常是呈现批次状,因此,为了最大程度利用有限的补偿能力,我们将对补偿任务进行一定程度的聚合之后,按批次进行下发,最大程度的补偿更多的实例。

最佳实践

这里我们主要展示如何使用 java SDK 创建伸缩规则,并采用 maven 进行依赖管理。创建目标追踪伸缩规则,需要使用 aliyun-java-sdk-ess 2.3.1 及以上版本。

程序所需的 maven 依赖如下:

        <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>aliyun-java-sdk-core</artifactId>
            <version>3.0.8</version>
        </dependency>
        <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>aliyun-java-sdk-ess</artifactId>
            <version>2.3.1</version>
        </dependency>

创建混合实例的成本优化伸缩组:

CreateScalingGroupRequest request = new CreateScalingGroupRequest();
request.setScalingGroupName(name);
request.setMinSize(0);
request.setMaxSize(100);
request.setVSwitchId(vsId);
request.setMultiAZPolicy("COST_OPTIMIZED");
request.setOnDemandBaseCapacity(onDemandBaseCapacity);
request.setOnDemandPercentageAboveBaseCapacity(onDemandPercentageAboveBaseCapacity);
request.setSpotInstanceRemedy(spotInstanceRemedy);
request.setSpotInstancePools(spotInstancePools);
CreateScalingGroupResponse response = client.getAcsResponse(request);

本文作者:tongkn

阅读原文

本文为云栖社区原创内容,未经允许不得转载。

退出移动版