ElastiCache ServerlessをCloudFormationとAWS CLIで構築してみた

2023.12.11

Amazon ElastiCache Serverlessはトラフィックパターンに応じてキャパシティがスケールし、高可用なクラスターがプロビジョンされます。 サーバーレスなため、ノードタイプやシャード数やレプリカ数などの指定は不要です。

AWSの公式ドキュメントで紹介されている、サーバーレス版ElastiCache for Redisの作成手順は極限までシンプルです *1

aws elasticache create-serverless-cache \
    --serverless-cache-name CacheName \
    --engine redis

とはいえ、実環境ではデフォルト値をカスタマイズする必要もあるでしょう。そのようなユースケース向けに、AWS CLIとCloudFormationでAmazon ElastiCache Serverlessを構築する手順を紹介します。

API について

ElastiCache Serverlessを作成するために ElastiCache::CreateServerlessCache という新しい API が割り当てられています。

クラスターの参照・変更・削除やスナップショット操作にもサーバーレス版の新しいAPIが割り当てられています。

主要パラメーター

ElastiCacheがサーバーレスになったことで、ユーザーが気をつけるべきパラメーターはスケール上限を指定する CacheUsageLimits だけです。

このパラメーターでは

  • データ上限
  • CPU

を指定します。

項目 パラメーター 範囲 デフォルト値 単位
データ上限 DataStorage 1-5000 5000 GB
計算上限 ECPUPerSecond 1,000-15,000,000 15,000,000 ECPU

ECPUは ElastiCache Processing Unitを表し、コマンドが消費したvCPUとデータサイズの大きい方を元にECPUを消費します。 デフォルトは上限値であり、利用者は CacheUsageLimits を設定することで、上限を下げる事ができます。 試算は難しいため、実際のワークロードで CloudWatch MetricのElastiCacheProcessingUnits を確認し、利用費も考慮しながら上限値を設定しましょう。

データサイズが DataStorage の上限に達すると Eviction やOut Of Memory (OOM)が発生し、ECPUが ECPUPerSecond の上限に達するとスロットリングが発生します。このあたりは直感どおりかと思います。

参考

設定できないパラメーター

ElastiCacheがサーバーレスになったことで、クラスター管理にまつわる多くのパラメーターを指定できなくなりました。

サーバーレス版は垂直にも水平にもスケールするため

  • ノードタイプ
  • シャード数

などの指定は不要です。

サーバーレス版はAWSが高可用性・対障害姓を担保しているため

  • レプリカ数
  • マルチAZ化

などの指定は不要です。

サーバーレス版はマイナーバージョンのアップグレードやパッチもダウンタイムなしに自動で適用するため、マイナーアップグレードの自動適用を指定するオプションも存在しません。

ElastiCache Serverless automatically applies the latest MINOR and PATCH software version to your cache, without any impact or downtime to your application. No action is required on your end.

https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/VersionManagement.html

デプロイしてみる

以上を踏まえて、次のような設定のサーバーレス版のElastiCache for Redisを AWS CLIとCloudFormationで作成します。

項目
エンジン Redis
エンジンバージョン 7
データサイズ上限 1GB
ECPU上限 1000

AWS CLIでデプロイ

aws elasticache create-serverless-cache \
    --serverless-cache-name redis-svl-cli \
    --description desc \
    --engine redis \
    --major-engine-version 7 \
    --cache-usage-limits DataStorage='{Maximum=1,Unit=GB}',ECPUPerSecond='{Maximum=1000}' \
    --security-group-ids sg-123 \
    --subnet-ids '["subnet-aaa","subnet-bbb","subnet-ccc"]' \
    --snapshot-retention-limit 7 \
    --daily-snapshot-time "17:30" \
    --tags Key=Envg,Value=Dev

CloudFormationでデプロイ

AWSTemplateFormatVersion: "2010-09-09"
Resources:
  SampleCluster:
    Type: AWS::ElastiCache::ServerlessCache
    Properties:
      ServerlessCacheName: redis-svl-cfn
      Description: desc
      Engine: redis
      MajorEngineVersion: 7
      CacheUsageLimits: 
        DataStorage: 
          Maximum: 1
          Unit: GB
        ECPUPerSecond: 
          Maximum: 1000
      SecurityGroupIds: 
        - sg-123
      SubnetIds: 
        - subnet-aaa
        - subnet-bbb
        - subnet-ccc
      SnapshotRetentionLimit: 7
      DailySnapshotTime: "17:30"
      Tags: 
        - Key: Env
          Value: Dev

ElastiCache for Redisの構成ごとのパラメーターを比較

ElastiCache for Redisは以下の3パターンが存在します(MemoryDB for Redisは除外)。

  • (初代)非クラスター型
  • クラスター型
    • self-designed : ユーザーがプロビジョン
    • serverless : re:Invent 2023で発表

これらをキャッシュ作成APIごとにパラメーターを比較してみましょう。

サーバーレス版がダントツでシンプルですね。

非クラスター型

APIドキュメント

create-cache-cluster
--cache-cluster-id <value>
[--replication-group-id <value>]
[--az-mode <value>]
[--preferred-availability-zone <value>]
[--preferred-availability-zones <value>]
[--num-cache-nodes <value>]
[--cache-node-type <value>]
[--engine <value>]
[--engine-version <value>]
[--cache-parameter-group-name <value>]
[--cache-subnet-group-name <value>]
[--cache-security-group-names <value>]
[--security-group-ids <value>]
[--tags <value>]
[--snapshot-arns <value>]
[--snapshot-name <value>]
[--preferred-maintenance-window <value>]
[--port <value>]
[--notification-topic-arn <value>]
[--auto-minor-version-upgrade | --no-auto-minor-version-upgrade]
[--snapshot-retention-limit <value>]
[--snapshot-window <value>]
[--auth-token <value>]
[--outpost-mode <value>]
[--preferred-outpost-arn <value>]
[--preferred-outpost-arns <value>]
[--log-delivery-configurations <value>]
[--transit-encryption-enabled | --no-transit-encryption-enabled]
[--network-type <value>]
[--ip-discovery <value>]
[--cli-input-json | --cli-input-yaml]
[--generate-cli-skeleton <value>]
[--debug]
[--endpoint-url <value>]
[--no-verify-ssl]
[--no-paginate]
[--output <value>]
[--query <value>]
[--profile <value>]
[--region <value>]
[--version <value>]
[--color <value>]
[--no-sign-request]
[--ca-bundle <value>]
[--cli-read-timeout <value>]
[--cli-connect-timeout <value>]
[--cli-binary-format <value>]
[--no-cli-pager]
[--cli-auto-prompt]
[--no-cli-auto-prompt]

self-designed型

APIドキュメント

  create-replication-group
--replication-group-id <value>
--replication-group-description <value>
[--global-replication-group-id <value>]
[--primary-cluster-id <value>]
[--automatic-failover-enabled | --no-automatic-failover-enabled]
[--multi-az-enabled | --no-multi-az-enabled]
[--num-cache-clusters <value>]
[--preferred-cache-cluster-azs <value>]
[--num-node-groups <value>]
[--replicas-per-node-group <value>]
[--node-group-configuration <value>]
[--cache-node-type <value>]
[--engine <value>]
[--engine-version <value>]
[--cache-parameter-group-name <value>]
[--cache-subnet-group-name <value>]
[--cache-security-group-names <value>]
[--security-group-ids <value>]
[--tags <value>]
[--snapshot-arns <value>]
[--snapshot-name <value>]
[--preferred-maintenance-window <value>]
[--port <value>]
[--notification-topic-arn <value>]
[--auto-minor-version-upgrade | --no-auto-minor-version-upgrade]
[--snapshot-retention-limit <value>]
[--snapshot-window <value>]
[--auth-token <value>]
[--transit-encryption-enabled | --no-transit-encryption-enabled]
[--at-rest-encryption-enabled | --no-at-rest-encryption-enabled]
[--kms-key-id <value>]
[--user-group-ids <value>]
[--log-delivery-configurations <value>]
[--data-tiering-enabled | --no-data-tiering-enabled]
[--network-type <value>]
[--ip-discovery <value>]
[--transit-encryption-mode <value>]
[--cluster-mode <value>]
[--serverless-cache-snapshot-name <value>]
[--cli-input-json | --cli-input-yaml]
[--generate-cli-skeleton <value>]
[--debug]
[--endpoint-url <value>]
[--no-verify-ssl]
[--no-paginate]
[--output <value>]
[--query <value>]
[--profile <value>]
[--region <value>]
[--version <value>]
[--color <value>]
[--no-sign-request]
[--ca-bundle <value>]
[--cli-read-timeout <value>]
[--cli-connect-timeout <value>]
[--cli-binary-format <value>]
[--no-cli-pager]
[--cli-auto-prompt]
[--no-cli-auto-prompt]

serverless型

APIドキュメント

  create-serverless-cache
--serverless-cache-name <value>
[--description <value>]
--engine <value>
[--major-engine-version <value>]
[--cache-usage-limits <value>]
[--kms-key-id <value>]
[--security-group-ids <value>]
[--snapshot-arns-to-restore <value>]
[--tags <value>]
[--user-group-id <value>]
[--subnet-ids <value>]
[--snapshot-retention-limit <value>]
[--daily-snapshot-time <value>]
[--cli-input-json | --cli-input-yaml]
[--generate-cli-skeleton <value>]
[--debug]
[--endpoint-url <value>]
[--no-verify-ssl]
[--no-paginate]
[--output <value>]
[--query <value>]
[--profile <value>]
[--region <value>]
[--version <value>]
[--color <value>]
[--no-sign-request]
[--ca-bundle <value>]
[--cli-read-timeout <value>]
[--cli-connect-timeout <value>]
[--cli-binary-format <value>]
[--no-cli-pager]
[--cli-auto-prompt]
[--no-cli-auto-prompt]

参考

脚注

  1. デフォルトのVPC・サブネット・セキュリティグループを活用