定时配置Serverless实例的RCU

Serverless实例RCU弹性伸缩的耗时通常为秒级,极小概率下可能因为跨机弹性扩容而耗时3~5分钟。如果您对特定时段的稳定性有严格要求,您可以定时配置Serverless实例的RCU,提前增加RCU数量。本文将介绍如何对RCU的范围进行周期性配置。

使用场景

  • Serverless实例会根据CPU和内存的负载情况进行弹性伸缩。自动弹性扩容的条件为CPU或内存使用率达到60%~80%的阈值范围。若在特定时段对CPU或内存的性能稳定性有较高要求,可提前手动调整RCU的下限配置。

  • 弹性扩容的方式分为本地弹性扩容和跨机弹性扩容两种。其中本地弹性扩容的耗时为秒级,跨机弹性扩容的耗时约为3~5分钟。在99.8%的场景下,本地的秒级弹性扩容可以满足Serverless的弹性扩容需求。然而,在本地资源不足的情况下,Serverless实例的弹性扩容需要跨机进行。由于跨机需要的时间较长,可能会对业务造成一定程度的影响。在特定时段内,为避免因自动弹性扩容未能及时完成而造成的影响,建议提前将RCU的上限和下限设置为相同的数值。

解决方案

使用定时任务调用ModifyDBInstanceSpec - 变更RDS实例API接口,在特定时段修改RCU的上下限,特定时段结束后恢复到默认的RCU上下限。

使用示例

如果需要在特定时段提升RCU下限,建议在该时段前10分钟,定时提升RCU下限,为可能出现的跨机情况预留一定时间,以确保特定时段内实例的稳定性。

例如,某项业务在早高峰时间08:00~09:00希望保证4~8 RCU的配置,可以在07:50分将RCU的下限提升至4,在09:00再恢复到0.5~8 RCU的默认配置。

image

Python示例

本示例使用APScheduler配置定时任务。

  1. 完成RAM授权、准备Python环境、配置环境变量、安装环境依赖等操作。

    1. 创建RAM用户并完成授权

    2. 准备Python环境

    3. 配置环境变量

    4. 安装依赖

  2. 打开命令行窗口执行如下命令,安装APScheduler。

    pip install apscheduler
  3. 下载示例代码。

    1. 访问ModifyDBInstanceSpec,进入该接口在OpenAPI门户的调试地址。

    2. 参数配置页签,配置如下参数。

    3. 参数

      描述

      取值

      DBInstanceId

      实例 ID。

      rm-bp1t8v93k6e15****

      PayType

      实例当前的付费类型。

      Serverless

      Direction

      实例变配类型。

      Serverless

      MaxCapacity

      RCU(Rds Capacity Unit)自动扩缩范围的上限。

      8.0

      MinCapacity

      RCU(Rds Capacity Unit)自动扩缩范围的下限。

      0.5

      AutoPause

      是否开启Serverless实例的智能暂停和启动。

      false

      SwitchForce

      是否开启Serverless实例的强制扩缩容。

      true

    4. 在右侧的SDK示例页签,选择Python语言,单击下载完整工程按钮,下载示例代码包。

    5. 说明

      建议下载SDK V2.0版本示例工程。

    6. 本地解压并进入alibabacloud_sample目录。

  4. 修改代码,配置定时任务。

    修改sample.py,增加APScheduler定时任务的内容,使用Cron触发器以设定定时任务的执行时间。例如,scheduler.add_job(my_scheduled_job, 'cron', hour=8, minute=0)代表每天的08时00分00秒。若您计划每日07:50设置RCU范围为[4, 8],并在每日09:00将RCU范围恢复为[0.5, 8],示例代码如下。

    sample.py

    # -*- coding: utf-8 -*-
    # This file is auto-generated, don't edit it. Thanks.
    import os
    import sys
    from typing import List, Dict
    from alibabacloud_rds20140815.client import Client as Rds20140815Client
    from alibabacloud_tea_openapi import models as open_api_models
    from alibabacloud_rds20140815 import models as rds_20140815_models
    from alibabacloud_tea_util import models as util_models
    from alibabacloud_tea_console.client import Client as ConsoleClient
    from alibabacloud_tea_util.client import Client as UtilClient
    from apscheduler.schedulers.blocking import BlockingScheduler
    
    class Sample:
        def __init__(self):
            pass
    
        @staticmethod
        def create_client() -> Rds20140815Client:
            """
            使用AK&SK初始化账号Client
            @return: Client
            @throws Exception
            """
            # 工程代码泄露可能会导致 AccessKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考。
            # 建议使用更安全的 STS 方式。
            config = open_api_models.Config(
                # 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID。,
                access_key_id=os.environ['ALIBABA_CLOUD_ACCESS_KEY_ID'],
                # 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_SECRET。,
                access_key_secret=os.environ['ALIBABA_CLOUD_ACCESS_KEY_SECRET']
            )
            # Endpoint 请参考 https://api.aliyun.com/product/Rds
            config.endpoint = f'rds.aliyuncs.com'
            return Rds20140815Client(config)
    
        # 调用API修改实例serverless配置。
        @staticmethod
        def modify_db_instance_spec(config: Dict[str, float]) -> None:
            """
            Modify DB instance spec - the core task function
            """
            client = Sample.create_client()
            serverless_configuration = rds_20140815_models.ModifyDBInstanceSpecRequestServerlessConfiguration(
                max_capacity=config['max_capacity'],
                min_capacity=config['min_capacity'],
                auto_pause=config['auto_pause'],
                switch_force=config['switch_force']
            )
            modify_dbinstance_spec_request = rds_20140815_models.ModifyDBInstanceSpecRequest(
                dbinstance_id='rm-bp1t8v93k6e15****',
                direction='Serverless',
                pay_type='Serverless',
                serverless_configuration=serverless_configuration
            )
            runtime = util_models.RuntimeOptions(
                read_timeout=50000,
                connect_timeout=50000
            )
            try:
                resp = client.modify_dbinstance_spec_with_options(modify_dbinstance_spec_request, runtime)
                ConsoleClient.log(UtilClient.to_jsonstring(resp))
            except Exception as error:
                # 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
                print(error.message)
                print(error.data.get("Recommend"))
                UtilClient.assert_as_string(error.message)
    
        @staticmethod
        def main(args: List[str]) -> None:
            """
    
            :rtype: object
            """
            # 初始化Scheduler
            scheduler = BlockingScheduler()
    
            # 配置8点的serverless参数
            config_8am = {
                'max_capacity': 8,
                'min_capacity': 4,
                'auto_pause': False,
                'switch_force': True
            }
    
            # 配置9点的serverless参数
            config_9am = {
                'max_capacity': 8,
                'min_capacity': 0.5,
                'auto_pause': False,
                'switch_force': True
            }
    
            # 配置定时任务
            scheduler.add_job(Sample.modify_db_instance_spec, 'cron', hour=7, minute=50, args=[config_8am])
            scheduler.add_job(Sample.modify_db_instance_spec, 'cron', hour=9, minute=0, args=[config_9am])
    
            try:
                scheduler.start()
            except (KeyboardInterrupt, SystemExit):
                pass
    
    if __name__ == '__main__':
        Sample.main(sys.argv[1:])
    
    

Java示例

本示例使用Spring Schedule配置定时任务。

说明

本示例需要安装Java 1.8以上开发环境。

  1. 完成RAM授权、配置环境变量等操作。

    1. 创建RAM用户并完成授权

    2. 配置环境变量

  2. 下载示例程序并在本地解压。

    示例程序请参见demo.zip

  3. 修改ScheduleTask.java的内容,根据实际情况配置定时任务。

    配置Cron表达式以设定定时任务的执行时间。其中,cron = "秒 分 时 日 月 周",详情请参见Cron

    例如,@Scheduled(cron = "0 0 8 * * ? ") 代表每天的08时00分00秒。若您计划每日07:50设置RCU范围为[4, 8],并在每日09:00将RCU范围恢复为[0.5, 8],示例代码如下。

    ScheduleTask.java

    package com.example.demo;
    
    import org.springframework.scheduling.annotation.Scheduled;
    import org.springframework.stereotype.Component;
    
    @Component
    public class ScheduleTask {
      
        @Scheduled(cron = "0 50 7 * * ? ")
        public void scheduleTask8am() {
            ModifySpecParams params = new ModifySpecParams();
            params.setRegionId("cn-hangzhou");
            params.setDBInstanceId("rm-bp1t8v93k6e15****");
            params.setDirection("Serverless");
            params.setPayType("Serverless");
            params.setAutoPause(false);
            params.setSwitchForce(true);
            params.setMaxCapacity(8);
            params.setMinCapacity(4);
            ModifyDBInstanceSpec.modify(params);
        }
    
        @Scheduled(cron = "0 0 9 * * ? ")
        public void scheduleTask9am() {
            ModifySpecParams params = new ModifySpecParams();
            params.setRegionId("cn-hangzhou");
            params.setDBInstanceId("rm-bp1t8v93k6e15****");
            params.setDirection("Serverless");
            params.setPayType("Serverless");
            params.setAutoPause(false);
            params.setSwitchForce(true);
            params.setMaxCapacity(8);
            params.setMinCapacity(0.5);
            ModifyDBInstanceSpec.modify(params);
        }
    }

    部分参数的含义如下,请用实际数值进行替换。

    参数

    描述

    示例

    RegionId

    实例所属地域。

    cn-hangzhou

    DBInstanceId

    实例ID。

    rm-bp1t8v93k6e15****

    PayType

    实例当前的付费类型。

    Serverless

    Direction

    实例变配类型。

    Serverless

    MaxCapacity

    RCU自动扩缩范围的上限。

    8.0

    MinCapacity

    RCU自动扩缩范围的下限。

    0.5

    AutoPause

    是否开启Serverless实例的智能暂停和启动。

    false

    SwitchForce

    是否开启Serverless实例的强制扩缩容。

    true