レプリカをオートスケールさせるAmazon Aurora Auto Scalingの導入ポイントをまとめてみた

Amazon Aurora Auto Scalingを利用すると、レプリカを動的にスケールアウトできます。 導入のポイントをまとめてみました。
2022.03.11

Amazon Auroraデータベースはリードレプリカを最大で15個まで追加できます。 Auto Scaling policyを設定することにより、利用者の多い日中はレプリカを多めに用意し、利用者の少ない夜間はレプリカを減らすといった運用が可能です。

この機能の設定ポイントを解説します。

Amazon Aurora Auto Scaling について

Amazon Aurora Auto Scaling はレプリカの平均CPU使用率・接続数に応じて、レプリカをオートスケールさせるサービスです。 スケールアウト方式のため、ワークロードに応じてレプリカ数を増減させるものであり、インスタンスタイプをスケールアップさせるわけではありません。

ECS でも利用されているターゲット追跡スケーリングポリシーのAmazon Auroraレプリカ版と考えるとわかりやすいかもしれません。

Amazon CloudWatch Alarm および Application Auto Scaling と連動してオートスケールするため、緩やかなワークロードの変化にはスムーズに追従しますが、スパイク的な増減は苦手です。

レプリカ群へアクセスするにはリーダーエンドポイントを利用

リーダーエンドポイントを利用すると、Auto Scalingと連動するレプリカ群にアクセスできます。

クエリの処理によって

  • 読み書き可能なクラスターエンドポイント
  • 読み取り専用のリーダーエンドポイント

のエンドポイントを振り分けるのは、クライアントの責務です。

アプリケーションでロジックを実装、あるいは、SQLによってエンドポイントを振り分ける MariaDB MaxScale のようなプロキシを導入してください。

Aurora Auto Scaling ポリシーについて

Aurora Auto Scaling ポリシー設定により、オートスケールなAurora レプリカ群がApplication Auto Scalingで管理されます。

  • ターゲット追跡スケールポリシー
  • スケールインポリシー
  • 最小・最大インスタンス数

を設定します。

ターゲット追跡スケールポリシー

ターゲット追跡スケールポリシーをもとに CloudWatch Alarm を作成し、しきい値を超えたら、スケールイン・アウトを発動します。

作成される CloudWatch Alarm の Threshold 設定から、なめらかワークロードの変化は得意だけど、スパイクは苦手なことが理解しやすいかと思います。

例えば Target Metric で

  • Target Metric : Average CPU utilization of Aurora Replicas
  • Target value : 50

とすると、スケールアウト向けには

  • Threshold : CPUUtilization > 50 for 3 datapoints within 3 minutes
  • Role : READER
  • Period : 1 minute
  • Datapoints to alarm : 3 out of 3

スケールイン向けには

  • Threshold : CPUUtilization < 45 for 15 datapoints within 15 minutes
  • Role : READER
  • Period : 1 minute
  • Datapoints to alarm : 15 out of 15

というアラームが作成されます。

速やかにスケールアウトし、緩やかにスケールインする設定です。 CloudWatch Alarm の 概要に "DO NOT EDIT OR DELETE. " とあるように、これらアラーム設定を直接変更・削除しないようにしましょう

Application Autoscaling サービスに問い合わせると、この設定を確認できます。

$ aws application-autoscaling \
  describe-scaling-policies \
  --service-namespace rds \
  --policy-names cpu

{
    "ScalingPolicies": [
        {
            "PolicyARN": "arn:aws:autoscaling:eu-central-1:1234:scalingPolicy:3fe0411d-529e-49e0-a2c6-3127196e8b8e:resource/rds/cluster:aurora3:policyName/cpu",
            "PolicyName": "cpu",
            "ServiceNamespace": "rds",
            "ResourceId": "cluster:aurora3",
            "ScalableDimension": "rds:cluster:ReadReplicaCount",
            "PolicyType": "TargetTrackingScaling",
            "TargetTrackingScalingPolicyConfiguration": {
                "TargetValue": 50.0,
                "PredefinedMetricSpecification": {
                    "PredefinedMetricType": "RDSReaderAverageCPUUtilization"
                },
                "ScaleOutCooldown": 300,
                "ScaleInCooldown": 300,
                "DisableScaleIn": false
            },
            "Alarms": [
                {
                    "AlarmName": "TargetTracking-cluster:aurora3-AlarmHigh-80fdf555-764c-43e9-842b-16441a276f5e",
                    "AlarmARN": "arn:aws:cloudwatch:eu-central-1:1234:alarm:TargetTracking-cluster:aurora3-AlarmHigh-80fdf555-764c-43e9-842b-16441a276f5e"
                },
                {
                    "AlarmName": "TargetTracking-cluster:aurora3-AlarmLow-16686cf8-d13c-471c-83e8-9e3f531637fe",
                    "AlarmARN": "arn:aws:cloudwatch:eu-central-1:1234:alarm:TargetTracking-cluster:aurora3-AlarmLow-16686cf8-d13c-471c-83e8-9e3f531637fe"
                }
            ],
            "CreationTime": "2022-03-10T12:27:31.657000+01:00"
        }
    ]
}

最小・最大インスタンス数

レプリカ数を0〜15の範囲で指定すると、Application Autoscalingが手動構築したレプリカと必要なレプリカ数のギャップを埋めるように動作します。

  • プライマリ x 1
  • レプリカ x 1

のクラスターに

  • 最小 : 2
  • 最大 : 5

を設定すると、新規にレプリカを1台追加し、クラスターのインスタンス数は 3台〜6台を遷移します。

Aurora Auto Scalingがスケールインで削除対象とするインスタンスは、自身がスケールアウトのために起動したインスタンスだけです。 手動追加したレプリカが削除されることはありません。

フェイルオーバーへの影響

Amazon Auroraでフェイルオーバーが発生すると、Priority(PromotionTier) 属性の値が最も低い(=優先度が高い)インスタンスの中からフェイルオーバー先を選定します。

インスタンス作成時のデフォルト値は1であり、Auto Scalingで追加されるインスタンスには優先度が最も低い 15 が設定されるため、通常はAuto Scalingインスタンスがフェイルオーバーターゲットになることはありません。

$ aws rds describe-db-clusters \
    --db-cluster-identifier mysql1 | jq '.DBClusters[0].DBClusterMembers'
[
  {
    "DBInstanceIdentifier": "application-autoscaling-89984640-17ec-4898-beb4-7f075fb5a1d4",
    "IsClusterWriter": false,
    "DBClusterParameterGroupStatus": "in-sync",
    "PromotionTier": 15
  },
  {
    "DBInstanceIdentifier": "application-autoscaling-a924a5c6-48a4-4019-8f21-9d93218fd261",
    "IsClusterWriter": false,
    "DBClusterParameterGroupStatus": "in-sync",
    "PromotionTier": 15
  },
  {
    "DBInstanceIdentifier": "mysql1-foo",
    "IsClusterWriter": true,
    "DBClusterParameterGroupStatus": "in-sync",
    "PromotionTier": 1
  },
  {
    "DBInstanceIdentifier": "mysql1-bar",
    "IsClusterWriter": false,
    "DBClusterParameterGroupStatus": "in-sync",
    "PromotionTier": 1
  }
]

時刻指定のスケールアウト

コンソールから設定可能なスケールポリシーは、インスタンス数をメトリクスと連動するものです。

イベントなどのために、時刻指定でスケールアウトさせたい場合、API application-autoscaling::put-scheduled-action で登録しましょう。

CRON 形式で日時を指定できます。

$ aws application-autoscaling put-scheduled-action \
  --service-namespace rds \
  --scheduled-action-name one-off-event \
  --resource-id cluster:mysql1 \
  --scalable-dimension rds:cluster:ReadReplicaCount \
  --scalable-target-action MinCapacity=2,MaxCapacity=8 \
  --schedule "at(2022-03-15T12:34:56)"
$


$ aws application-autoscaling describe-scheduled-actions \
  --service-namespace rds \
  --resource-id cluster:mysql1
{
    "ScheduledActions": [
        {
            "ScheduledActionName": "one-off-event",
            "ScheduledActionARN": "arn:aws:autoscaling:eu-central-1:1234:scheduledAction:56e7f5ae-6447-4c36-80fa-058bd66d368b:resource/rds/cluster:mysql1:scheduledActionName/one-off-event",
            "ServiceNamespace": "rds",
            "Schedule": "at(2022-03-15T12:34:56)",
            "ResourceId": "cluster:mysql1",
            "ScalableDimension": "rds:cluster:ReadReplicaCount",
            "ScalableTargetAction": {
                "MinCapacity": 2,
                "MaxCapacity": 8
            },
            "CreationTime": "2022-02-24T16:46:59.170000+01:00"
        }
    ]
}

カスタムエンドポイントへの影響

Amazon Aurora は指定したインスタンスからなるカスタムエンドポイントを定義できます。

例えば、BI 向けに特定のレプリカを指定し、BI以外には、残りのレプリカを利用するといったことが可能です。

Auto Scaling で追加されたインスタンスをカスタムエンドポイントに含めたい場合、エンドポイント設定の「今後追加されるインスタンスをこのクラスターにアタッチする(Attach future instances added to this cluster)」をチェックしましょう。

アプリケーションの動作確認

繰り返しとなりますが、Aurora Auto Scalingはレプリカをオートスケールさせるものであり、クエリの処理によって

  • 読み書き可能なクラスターエンドポイント
  • 読み取り専用のリーダーエンドポイント

のエンドポイントを振り分けるのは、クライアントの責務です。

リーダーエンドポイントを利用するように実装した後は

  • スケールアウトしたときに、新しいインスタンスに接続すること
  • スケールインしたときに、削除されたインスタンスに接続し続けないこと

を確認しましょう。

sysbench で負荷をかけてオートスケールさせる

sysbench を使うと、オートスケール用の負荷をかんたんにかけることができます。

クラスターエンドポイントに向けて、データを初期化し(oltp_common prepare)

$ sysbench  \
    --mysql-host=XXX.cluster-ro-c75dvgjlkohb.eu-central-1.rds.amazonaws.com \
    --mysql-port=3306 \
    --mysql-db=test \
    --mysql-user=admin \
    --mysql-password=YOUR-PASSWORD \
    --tables=3 \
    --table_size=10000 \
    oltp_common prepare

リードエンドポイントに向けて、参照系負荷(oltp_read_only)をかけます

$ sysbench  \
    --mysql-host=XXX.cluster-ro-c75dvgjlkohb.eu-central-1.rds.amazonaws.com \
    --mysql-port=3306 \
    --mysql-db=test \
    --mysql-user=admin \
    --mysql-password=YOUR-PASSWORD \
    --tables=3 \
    --table_size=100 \
    --threads=2 \
    --time=600 \
    oltp_read_only run

最後に

Amazon Auroraのレプリカは Application AutoScaling と連動し、参照性能をかんたんにスケールアウトできます。

大前提として、アプリケーションが更新用のクラスターエンドポイントと参照用のリーダーエンドポイントを使い分けている必要があり、スパイクには追従できないことにご注意ください。

また、本機能はあくまでも参照のスケールアウトであり、書き込み性能をスケールさせるには、データベースのチューニング(インデックス、パラメーター、など)やスケールアップさせる必要があります。

Amazon Aurora Serverless v2 はスケールアウトにもスケールアップにも対応しているようなので、リリースが待ち遠しいです。

それでは。

参考