目次
PJ 役割分担と本記事の前提
前提:複数の役割を兼任する場合もあるが、以下で人物定義する。
- アプリケーション開発者
AWS上で稼動するシステムのアプリケーションを開発する人を指す。ざっくりなくくりとしては、ソースコードを扱う人。 - システムの管理者
システムを監視、運用する人を指す。一般的には、AWSを所有する顧客自身になるケースが多い。 - インフラ(AWSサービス)担当者
AWSのサービスを構築し、アプリケーションが動作するための基盤(サーバやコンテナなど)を構築するする人を指す。本記事は、この担当者目線での記事となる。 
以下の役割分担を想定し、本記事はインフラ担当者向けに整理している。
| 作業 | 担当者 | 
|---|---|
| ElastiCacheの設計(パラメータ設計) | インフラ担当者(承認:システム管理者) | 
| ElastiCacheの構築 | インフラ担当者(承認:システム管理者) | 
| ElastiCacheを使用したアプリの構築 | アプリケーション開発者(承認:システム管理者) | 
| ElastiCacheの運用(障害時リストアなど) | システム管理者 | 
ElastiCacheのユースケース
ユースケースとしては、以下。キャッシュに限らず様々な用途で利用される。(図はBlack Beltより引用)

一言にキャッシュと言っても、以下のように様々なサービスのキャッシュとして利用できる

Webのセッション管理にも利用されるケースが多い。

ElastiCacheの用語
AWSコンソール上の用語(上図)と、CLIでの用語(下図)の概要図。

以下、用語の解釈と補足。
- クラスター:
- シャードの集合。シャードごとにデータベースのようなデータの論理的な境界ができるわけではなく負荷分散の用途で複数のシャードを持つ。シャードにはスロットという番号が割り振られており、クラスターへの書き込み時に、書き込むキーに対してスロット計算が行われ、該当スロットを保有するシャードに対してデータが書き込まれる動作となる。※1. そのため、シャードが複数ある場合には複数のシャードにキーが分散する形になる。
※1. スロット計算のイメージは以下。図の例では、Key: foo を書き込む際に、スロット計算(赤字)が行われ、該当スロット(12182)を保有するSHARD-3に書き込まれている。 
 - シャードの集合。シャードごとにデータベースのようなデータの論理的な境界ができるわけではなく負荷分散の用途で複数のシャードを持つ。シャードにはスロットという番号が割り振られており、クラスターへの書き込み時に、書き込むキーに対してスロット計算が行われ、該当スロットを保有するシャードに対してデータが書き込まれる動作となる。※1. そのため、シャードが複数ある場合には複数のシャードにキーが分散する形になる。
 

参考)
Amazon ElastiCache for Redis でクラスターモードを使用する
ElastiCache (Redis)のクラスターモードの作成メモ
- シャード:
- ノードの集合。書き込み可能なノードであるプライマリノードと、読み取り専用のレプリカノードから成る。
 
 
- ノード:
- データの書き込み、読み込み先のメモリ領域であり、書き込み先になるのがプライマリノード。レプリカノードはプライマリのレプリカであり、プライマリ障害時にはプライマリに昇格(フェイルオーバ)できる。
参考)ノードの管理 
 - データの書き込み、読み込み先のメモリ領域であり、書き込み先になるのがプライマリノード。レプリカノードはプライマリのレプリカであり、プライマリ障害時にはプライマリに昇格(フェイルオーバ)できる。
 
ElastiCacheの設計
以降、パラメータサンプルを記載する。各パラメータの決め方は、大きく以下3通り。
- アプリ要件:アプリケーション要件を、アプリケーション開発者にヒアリングして確定する。
 - サービスのXX要件:可用性要件や保守性要件など、サービス全体の要件から確定する部分。システム管理者にヒアリングして確定する。
 - 任意:基本的にシステム管理者が任意に決められるため、システム管理者による指定、又はインフラ担当者にて候補提示してシステム管理者に承認頂く形で確定。
 
ElastiCache(Redis)設定
| 項目 | 設定例 | 決め方 | 備考 | 
|---|---|---|---|
| クラスターモード | 有効 | サービスの可用性および拡張性要件。 AZ障害時のダウンタイムや、プライマリノードを増加する可能性がある場合には有効化する。  | クラスタモードの詳細はこちら | 
| クラスター名 | [$systemname]-[$env]-elasticache | 任意 | |
| マルチAZ | 有効 | サービスの可用性要件。 | |
| 自動フェイルオーバー | 有効 | サービスの可用性要件。 クラスタモードが有効の場合は、強制的に有効。  | |
| Redisエンジンバージョン | 7.0 | アプリ要件 | |
| ポート番号 | 6379 | アプリ要件 | |
| パラメータグループ | <Cfn接頭文字>-XXX | アプリ要件 | Cfn作成時は自動で名称割り当て | 
| ノードのタイプ | cache.r6g.large | サービスの性能要件。 サービス利用のピーク時でも許容可能なサイズにする。  | |
| シャード数 | 3 | サービスの性能要件。 | |
| シャードあたりのレプリカ | 2 | サービスの可用性要件。 | |
| ネットワークタイプ | IPv4 | サービスの通信要件。 | |
| サブネットグループ | [$systemname]-[$env]-elasticache-subnet-group | サービスの通信要件。 接続元に応じて、パブリックまたは、プライベートのサブネットを指定。(サブネットグループ名称自体は任意)  | |
| スロットおよびキースペース | 均等分散 | アプリ要件 通常「均等分散」で問題ない。特定のキーのみ大きなオブジェクトを持つような場合には、「カスタム分散」を使用して、シャードの負荷が均等になるようにする。  | |
| AZ 配置 | プライマリ:ap-northeast-1a レプリカ1:ap-northeast-1c レプリカ2:ap-northeast-1c  | サービスの可用性要件。 | |
| 保管時の暗号化 | 有効 | サービスのセキュリティ要件。 (暗号化によるパフォーマンス影響が発生する可能性がある。)  | |
| 送信中の暗号化 | 無効 | サービスのセキュリティ要件。 (暗号化によるパフォーマンス影響が発生する可能性がある。)  | |
| セキュリティグループ | [$systemname]-[$env]-elasticache-sg | サービスの通信要件(グループ名称自体は任意) | |
| 自動バックアップ | 有効 | サービスの可用性要件。 | |
| バックアップ保存期間(1〜35日) | 7日 | サービスの保管要件。 | |
| バックアップウィンドウ | 16:00-17:00 | サービスの可用性要件。 一日の静止点となる時点で取得する。  | 日本時間 01:00-02:00 (日次バックアップ) | 
| メンテナンスウィンドウ | sun:18:00-sun:19:00 | サービスの可用性要件。 メンテナンスによって停止する可能性があるため、サービス停止可能な時間帯を指定。  | 日本時間 月曜日 03:00-04:00 | 
| マイナーバージョンの自動アップグレード | 無効 | サービス保守性要件。 アップデートを手動コントロールしたい場合は、無効化。  | |
| SNS通知 | 無効 | サービスの保守性(監視)要件。 障害検知時の通知用。  | |
| スローログ | CloudWatch:JSON | サービスの保守性(監視)要件。 主に障害調査用。  | |
| エンジンログ | CloudWatch:JSON | サービスの監視要件。 主に障害調査用。  | |
| 設定エンドポイント | <クラスター名>.xxxx:6379 | 自動生成 | クラスター名に応じて自動生成。 | 
※1. ログはCloud Watch Logsへ出力するが、保管用と監視用の2つの要件がある場合には、以下のようにS3を併用する構成にするとコストメリットがある。
- Cloud Watch Logsのログには失効期間を設ける。→直近の監視用
 - Cloud Watch Logsからサブスクリプションフィルターを利用してFirehose経由でS3に転送する。→長期保管用
 
パラメータグループ設定
| 項目 | 設定例 | 決め方 | 備考 | 
|---|---|---|---|
| グループ名 | <Cfn接頭文字>-XXX | 任意 (CFn作成の場合は自動採番)  | |
| ファミリー | redis6.x | アプリ要件 | |
| 説明 | [$systemname]-[$env]-elasticache-parameter-group | 任意 | 
以下の項目を設定。その他デフォルト値。
| 項目 | 設定例 | 決め方 | 備考 | 
|---|---|---|---|
| cluster-enabled | yes | クラスタモードが有効な場合に設定 |  | 
サブネットグループ設定
[$systemname]-[$env]-elasticache-subnet-group
| アベイラビリティゾーン | サブネット | 決め方 | 備考 | 
|---|---|---|---|
| ap-northeast-1a | [$systemname]-[$env]-private-subnet01a | elasticacheが稼動するサブネットを指定。 |  | 
| ap-northeast-1c | [$systemname]-[$env]-private-subnet01c | elasticacheが稼動するサブネットを指定。 | 
構築
上記設定例を使用した場合のCloud Formationコード。(プライベートサブネット×2 でElastiCacheを稼動)
AWSTemplateFormatVersion: 2010-09-09
Metadata:
  AWS::CloudFormation::Interface:
    ParameterGroups:
      - Label:
          default: Common Setting
        Parameters:
          - SystemName
          - EnvType
          
Parameters:
  SystemName:
    Type: String
    Default: demo
  EnvType:
    Type: String
    Default: prod
  
Resources:
# VPC
  ## VPC CIDR
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
      EnableDnsSupport: true
      EnableDnsHostnames: true
      InstanceTenancy: default
      Tags:
        - Key: Name
          Value: !Sub ${SystemName}-${EnvType}-vpc
        
          
  ## Private-Subnet01a
  PrivateSubnet01a:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      AvailabilityZone: ap-northeast-1a
      CidrBlock: 10.0.0.0/24
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: !Sub ${SystemName}-${EnvType}-private01a
  ## Private-Subnet01c
  PrivateSubnet01c:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      AvailabilityZone: ap-northeast-1c
      CidrBlock: 10.0.1.0/24
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: !Sub ${SystemName}-${EnvType}-private01c   
  ## CloudWatch logGroup ElastiCache slowlog
  ElastiCacheSlowLogGroup:
    Type: AWS::Logs::LogGroup
    Properties: 
      LogGroupName: !Sub ${SystemName}-${EnvType}-elasticache/slowlog
      RetentionInDays: 30
 
  ## CloudWatch logGroup ElastiCache slowlog
  ElastiCacheEngineGroup:
    Type: AWS::Logs::LogGroup
    Properties: 
      LogGroupName: !Sub ${SystemName}-${EnvType}-elasticache/enginelog
      RetentionInDays: 30
  ## rdsSecuritygroup
  elasticacheSecuritygroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupName: !Sub ${SystemName}-${EnvType}-elasticache-sg
      GroupDescription: !Sub ${SystemName}-${EnvType}-elasticache-sg
      Tags:
        - Key: Name
          Value: !Sub ${SystemName}-${EnvType}-elasticache-sg  
      VpcId: !Ref VPC
      SecurityGroupIngress:
      - IpProtocol: TCP
        FromPort: 6379
        ToPort: 6379
        CidrIp: 10.0.0.0/16
        
  ElastiCacheSubnetGroup:
    Type: AWS::ElastiCache::SubnetGroup
    Properties:
      CacheSubnetGroupName: !Sub ${SystemName}-${EnvType}-elasticache-subnet-group
      Description: !Sub ${SystemName}-${EnvType}-elasticache-subnet-group
      SubnetIds:
        - !Ref PrivateSubnet01a
        - !Ref PrivateSubnet01c
      Tags:
      - Key: Name
        Value: !Sub ${SystemName}-${EnvType}-elasticache-subnet-group
  ElastiCacheParameterGroup:
    Type: AWS::ElastiCache::ParameterGroup
    Properties:
      Description: !Sub ${SystemName}-${EnvType}-elasticache-parameter-group
      CacheParameterGroupFamily: redis6.x
      Properties:
        cluster-enabled: "yes"
        
  ElastiCacheReplicationGroup:
    Type: 'AWS::ElastiCache::ReplicationGroup'
    Properties:
      ReplicationGroupDescription: !Sub ${SystemName}-${EnvType}-elasticache
      NumNodeGroups: 3   ###シャード数
      ReplicasPerNodeGroup: 2  ##シャードあたりのレプリカノードの数
      NodeGroupConfiguration:
        - 
          PrimaryAvailabilityZone: ap-northeast-1a
          ReplicaAvailabilityZones:
            - ap-northeast-1c
            - ap-northeast-1c
        - 
          PrimaryAvailabilityZone: ap-northeast-1a
          ReplicaAvailabilityZones:
            - ap-northeast-1c
            - ap-northeast-1c
        - 
          PrimaryAvailabilityZone: ap-northeast-1a
          ReplicaAvailabilityZones:
            - ap-northeast-1c
            - ap-northeast-1c
      CacheNodeType: cache.r6g.large
      AutomaticFailoverEnabled: true
      MultiAZEnabled: true
      CacheSubnetGroupName: !Ref ElastiCacheSubnetGroup
      CacheParameterGroupName: !Ref ElastiCacheParameterGroup
      Engine: redis
      EngineVersion: 6.2
      ReplicationGroupId: !Sub ${SystemName}-${EnvType}-elasticache
      Port: 6379
      SecurityGroupIds:
        - !Ref elasticacheSecuritygroup
      AtRestEncryptionEnabled: true
      TransitEncryptionEnabled: false
      PreferredMaintenanceWindow: sun:18:00-sun:19:00
      SnapshotWindow: 16:00-17:00
      SnapshotRetentionLimit: 7
      LogDeliveryConfigurations: 
        - DestinationDetails:
            CloudWatchLogsDetails: 
              LogGroup: !Sub ${SystemName}-${EnvType}-elasticache/slowlog
          DestinationType: cloudwatch-logs
          LogFormat: JSON
          LogType: slow-log
        - DestinationDetails:
            CloudWatchLogsDetails: 
              LogGroup: !Sub ${SystemName}-${EnvType}-elasticache/enginelog
          DestinationType: cloudwatch-logs
          LogFormat: JSON
          LogType: engine-log接続テスト方法
- 前提条件
- 必要なポート接続が可能(セキュリティグループおよびルーティングの設定ができている。)
 
 - 必要なポート接続が可能(セキュリティグループおよびルーティングの設定ができている。)
 - 接続元のOSによって、必要な準備(クライアントソフトインストール)や接続コマンドが異なるため、こちらの手順を参照。
 
アプリからの利用方法(キャッシュ書き込みなど)
- アプリケーションからElastiCacheにキャッシュを書き込む等のコーディング方法は、こちらのハンズオンを参照
 
- なお、アプリ側では、キャッシュの書き込みタイミングや有効期限(TTL)などをどうするか検討が必要。
参考)キャッシュ戦略 
運用
バックアップ
バックアップは、自動バックアップと手動バックアップの2種類がある。
- 自動バックアップは、設定したバックアップウィンドウ内で自動的に実行される。
 - 手動バックアップは、任意のタイミングで実施可能。
 
リストア
リストア動作
既存のクラスタを、復旧時点に戻すのではなく、新たにクラスタを作成して復旧することになる。
リストア手順
リストアによる、アプリ側の改修(接続するためのエンドポイント変更)を避ける場合、クラスタ名(エンドポイント)を変更することができないため、以下1択。
- 既存のクラスタを削除して、既存と同名のクラスタ名で復元する。
 
