🎉

【CFn】DynamoDB のLSI・GSIとCFnでのDynamoDBAutoScalingの設定の仕方を確認する。

2022/10/31に公開

今回はDynamoDBに触れてみます。

今回は公式のサンプルテンプレートから

・「DynamoDBテーブル」
・「セカンダリインデックスを使用したDynamoDB」

オートスケーリング用のテンプレートを用意しています。

それぞれ覗いていきたいと思います。

DynamoDB Tableのみ

プロパティの説明やドキュメント上の必須項目であるか否かをコメントで添えています。

DynamoDB_table
DynamoDB_table.yml
AWSTemplateFormatVersion: 2010-09-09
Description: >-
  AWS CloudFormation Sample Template DynamoDB_Table: This template demonstrates
  the creation of a DynamoDB table.  **WARNING** This template creates an Amazon
  DynamoDB table. You will be billed for the AWS resources used if you create a
  stack from this template.
# ============== パラメータ ==============
Parameters:

  HashKeyElementName: # 属性の名前
    Description: HashType PrimaryKey Name
    Type: String # パラメータのタイプ
    AllowedPattern: '[a-zA-Z0-9]*' # 正規表現
    MinLength: '1'  # 最小文字数
    MaxLength: '2048' #最大文字数
    ConstraintDescription: must contain only alphanumberic characters #正規表現外の入力に対してのエラー文。

  HashKeyElementType: # 文字列かNumber
    Description: HashType PrimaryKey Type
    Type: String
    Default: S # テキストボックスの初期入力値。
    AllowedPattern: '[S|N]'
    MinLength: '1'
    MaxLength: '1'
    ConstraintDescription: must be either S or N

  ReadCapacityUnits: # RCUを指定
    Description: Provisioned read throughput
    Type: Number
    Default: '5'
    MinValue: '5' # 最小数値
    MaxValue: '10000' #最大数値
    ConstraintDescription: must be between 5 and 10000

  WriteCapacityUnits: # WCUを指定
    Description: Provisioned write throughput
    Type: Number
    Default: '10'
    MinValue: '5'
    MaxValue: '10000'
    ConstraintDescription: must be between 5 and 10000
# ============== リソース ==============
Resources:
  myDynamoDBTable:
    Type: 'AWS::DynamoDB::Table'
    Properties:
      AttributeDefinitions: #[必須: 条件付き] テーブルとインデックスのキー スキーマを記述する属性のリスト。このプロパティは、DynamoDB テーブルを作成するために必要です。
        - AttributeName: !Ref HashKeyElementName #[必須: はい] 属性の名前。
          AttributeType: !Ref HashKeyElementType #[必須: はい] 属性のデータ型。[S 文字列型 | N Number型 | B Binary]
      KeySchema: #[必須: はい] テーブルの主キーを構成する属性を指定。
        - AttributeName: !Ref HashKeyElementName #
          KeyType: HASH #
      ProvisionedThroughput: #[]指定されたテーブルのスループット。ReadCapacityUnitsとWriteCapacityUnitsの値で構成される。
        ReadCapacityUnits: !Ref ReadCapacityUnits #[必須: はい]DynamoDBがThrottlingExceptionを返す前に、1秒間に消費される強い一貫性のある最大読み込み回数。
        WriteCapacityUnits: !Ref WriteCapacityUnits #[必須: はい] DynamoDBがThrottlingExceptionを返すまでの、1秒間に消費される最大書き込み回数
# ============== 出力 ==============
Outputs:
  TableName:
    Value: !Ref myDynamoDBTable # AWS::DynamoDB::TableをRefするとテーブル名が返る。
    Description: Table name of the newly created DynamoDB table

スタック作成します。

パラメータを入力→次へ→次へ→スタックの作成

CREATE_COMPLETE

そのままセカンダリインデックス有りのテンプレートも作成してみます。

DynamoDB LSI・GSI有り

先程のテンプレートになかった項目のみ説明コメントを追加しています。

DynamoDB_with_secondary_indexes
DynamoDB_with_secondary_indexes.yaml
AWSTemplateFormatVersion: 2010-09-09
Description: >-
  AWS CloudFormation Sample Template DynamoDB_Secondary_Indexes: Create a
  DynamoDB table with local and global secondary indexes. **WARNING** This
  template creates an Amazon DynamoDB table. You will be billed for the AWS
  resources used if you create a stack from this template.

# ============== パラメータ ==============
Parameters:

  ReadCapacityUnits:  # RCU
    Description: Provisioned read throughput
    Type: Number
    Default: '5'
    MinValue: '5'
    MaxValue: '10000'
    ConstraintDescription: must be between 5 and 10000

  WriteCapacityUnits: #WCU
    Description: Provisioned write throughput
    Type: Number
    Default: '10'
    MinValue: '5'
    MaxValue: '10000'
    ConstraintDescription: must be between 5 and 10000

# ============== リソース ==============
Resources:

  TableOfBooks:
    Type: 'AWS::DynamoDB::Table'
    Properties:
      AttributeDefinitions:
        - AttributeName: Title
          AttributeType: S
        - AttributeName: Category
          AttributeType: S
        - AttributeName: Language
          AttributeType: S
      KeySchema:
        - AttributeName: Category
          KeyType: HASH
        - AttributeName: Title
          KeyType: RANGE
      ProvisionedThroughput:
        ReadCapacityUnits: !Ref ReadCapacityUnits
        WriteCapacityUnits: !Ref WriteCapacityUnits
      LocalSecondaryIndexes: #[必須: いいえ] テーブルに作成されるLSI。最大5つ作成可能。各インデックスは最大10ギガバイトの特定のハッシュキー値にスコープされる。LSIは親テーブル作成時のみ作成可能。
        - IndexName: LanguageIndex # [必須: はい] LSIの名前。テーブル内の全てのインデックス内で一意である必要あり。
          KeySchema: #[必須: はい] 属性名とキータイプの1つ以上のペアで構成されるLSIの完全なキースキーマ。
            - AttributeName: Category #[必須: はい] キー属性の名前。
              KeyType: HASH #[必須: はい] このキー属性が引き受ける役割。[HASH- パーティションキー | RANGE- ソートキー ]
            - AttributeName: Language 
              KeyType: RANGE  
          Projection: #[必須: はい] テーブルからLSIにコピー(射影)される属性。これらは自動的に射影される主キー属性と索引キー属性に追加されます。
            ProjectionType: KEYS_ONLY #[必須: いいえ] インデックスに射影される属性のセット。[KEYS_ONLY -インデックスと主キーのみがインデックスに射影される。| INCLUDE- KEYS_ONLYで説明されている属性に加えてセカンダリインデックスには指定した他の非キー属性が含まれる。| ALL- 全テーブル属性がインデックスに射影される。]
      GlobalSecondaryIndexes: #[必須: いいえ] テーブルに作成されるGSI。最大20個。
        - IndexName: TitleIndex #[必須: はい] 
          KeySchema: #[必須: はい] 
            - AttributeName: Title #[必須: はい] 
              KeyType: HASH #[必須: はい] 
          Projection: #[必須: はい] 
            ProjectionType: KEYS_ONLY #[必須: いいえ] 
          ProvisionedThroughput: 
            ReadCapacityUnits: !Ref ReadCapacityUnits 
            WriteCapacityUnits: !Ref WriteCapacityUnits 

# ============== 出力 ==============
Outputs:
  TableName:
    Value: !Ref TableOfBooks
    Description: Name of the newly created DynamoDB table

パラメータを入力→次へ→次へ→スタックの作成

CREATE_COMPLETE

それぞれを見て見ます

DynamoDBコンソールに移動すると無事2つのスタックから2つのテーブルが作成されています。

それぞれのキーやパラメータで指定したRCU・WCUも反映されています。
後者のテーブルではインデックスが「2」になっています。

インデックスなしのテーブルの概要から設定を確認してみます。

キャパシティモードの「プロビジョンド」をクリックすると
文字が重なっていてわかりにくいですが、テーブル一覧画面と同様にRCU・WCUが確認出来ます。

次にインデックスありのテーブルです。

インデックスが「1グローバル、1ローカル」になっています。

隣のインデックスタブを表示します。

テンプレートで指定したインデックス名やProjectionType: KEYS_ONLYなど反映されています。

※余談ですがLSI側にGSIのように「インデックスを作成する」ボタンがないのは、LSIはテーブル作成時のみ作成可能であるからです。

RCUとWCUの数字の下に「オートスケーリングはオフです。」と表示があります。

ドキュメントを読んでみると、

AWS Management Console を使用してテーブルまたはグローバルセカンダリインデックスを作成すると、デフォルトで DynamoDB Auto Scaling が有効になります。

とあります。

CloudFormationでのAutoScalingの設定方法については「AWS CloudFormation を使用して Amazon DynamoDB テーブルとインデックスの Auto Scaling を設定する方法」を確認してみます。

詳細な説明はリンク先にありましたので割愛しますがページ下部に設置されている[Launch Stack]ボタンの先のS3の中には既に2018年3月27日時点では存在していたと思われるテンプレートファイルは削除されていました。

以下に同じテンプレートを用意しています。

DynamoDB_WCU_AutoScaling
DynamoDB_WCU_AutoScaling.yaml
AWSTemplateFormatVersion: "2010-09-09"

# ============== パラメータ ==============
Parameters: 

  userTableName: 
    Type: String
    Default: "myapp.User"
    Description: "Name of the user table"

  userIndexName: 
    Type: String
    Default: "user-city-index"
    Description: "Name of the user index"
# ============== リソース ==============
Resources: 
# -------------- IAM --------------
# ロール
  ScalingRole: 
    Type: "AWS::IAM::Role"
    Properties: 
      AssumeRolePolicyDocument: 
        Version: "2012-10-17"
        Statement: 
        - 
          Effect: Allow
          Principal: 
            Service: 
              - "application-autoscaling.amazonaws.com"
          Action: 
            - "sts:AssumeRole"
      Path: "/"
      Policies: 
        - PolicyName: root
          PolicyDocument: 
            Version: "2012-10-17"
            Statement: 
              - Effect: Allow
                Action:          
                - "dynamodb:DescribeTable"
                - "dynamodb:UpdateTable"
                - "cloudwatch:PutMetricAlarm"
                - "cloudwatch:DescribeAlarms"
                - "cloudwatch:GetMetricStatistics"
                - "cloudwatch:SetAlarmState"
                - "cloudwatch:DeleteAlarms"
                Resource: "*"
# -------------- ApplicationAutoScaling--------------
  # ターゲット
  UserTableWriteCapacityScalableTarget: 
    Type: "AWS::ApplicationAutoScaling::ScalableTarget"
    Properties: 
      MaxCapacity: 100
      MinCapacity: 5   
      ResourceId: !Sub table/${userTableName}
      RoleARN: !GetAtt ScalingRole.Arn
      ScalableDimension: "dynamodb:table:WriteCapacityUnits"
      ServiceNamespace: dynamodb

  UserIndexWriteCapacityScalableTarget: 
    Type: "AWS::ApplicationAutoScaling::ScalableTarget"
    Properties: 
      MaxCapacity: 100
      MinCapacity: 5
      ResourceId: !Sub table/${userTableName}/index/${userIndexName}
      RoleARN: !GetAtt ScalingRole.Arn
      ScalableDimension: "dynamodb:index:WriteCapacityUnits"
      ServiceNamespace: dynamodb

  # ポリシー
  UserTableWriteScalingPolicy: 
    Type: "AWS::ApplicationAutoScaling::ScalingPolicy"
    Properties: 
      PolicyName: WriteAutoScalingPolicy
      PolicyType: TargetTrackingScaling
      ScalingTargetId: 
        Ref: UserTableWriteCapacityScalableTarget
      TargetTrackingScalingPolicyConfiguration: 
        TargetValue: 70
        ScaleInCooldown: 60
        ScaleOutCooldown: 60
        PredefinedMetricSpecification: 
          PredefinedMetricType: DynamoDBWriteCapacityUtilization

# -------------- DynamoDBテーブル --------------
  tableMyAppUser: 
    Type: "AWS::DynamoDB::Table"
    Properties: 
      TableName: 
        Ref: userTableName
      AttributeDefinitions: 
        - AttributeName: userId
          AttributeType: S
        - AttributeName: city
          AttributeType: S
        - AttributeName: signupDate
          AttributeType: S
      KeySchema:  
        - AttributeName: userId
          KeyType: HASH
      ProvisionedThroughput: 
        ReadCapacityUnits: 5
        WriteCapacityUnits: 5
      GlobalSecondaryIndexes: 
        - IndexName: !Ref userIndexName
          KeySchema: 
            - AttributeName: city
              KeyType: HASH
            - AttributeName: signupDate
              KeyType: RANGE
          Projection: 
            ProjectionType: ALL
          ProvisionedThroughput: 
            ReadCapacityUnits: 5
            WriteCapacityUnits: 5

パラメータを入力→次へ→次へ→スタックの作成

CREATE_COMPLETE

テーブルが無事作成されました。
指定した書き込みキャパシティユニット(WCU)のみ「AutoScalingをプロビジョニング済み」と表示されています。

「インデックス」タブのGSIも以下のように表示されています。

以上でした。

有難うございました。

Discussion