ElastiCacheRedisのCloudFormationで混乱したところを整理した

祝!はてなブログhttps化!🎉httpsになったのでブログを書いていこうと思います!

CloudFormationでElastiCache Redisクラスターを構築した時に混乱したことを整理してみました。長くなってしまったのでまとめだけ見れば問題ないと思います。

はじめに

CloudFormationでリソースを作成する場合、構築したいメインのリソースを中心にドキュメントを読んでいけば、関連するそれ以外の必要なリソースもわかるので、まずは中心となるリソースを見つけるのがおすすめです。

たとえば、Auroraの場合だとAWS::RDS::DBClusterというのがあるのでこれのプロパティに必要なリソースを定義していけば良いというのがわかります。

ElastiCacheの場合もDBなのでAuroraの設定に近い構成になると踏んでいました。Clusterっぽいリソースがあってそこに色々追加していく感じです。実際、AWS::ElastiCache::CacheClusterというリソースがあったのでこれを使えば良いんだろうと考えました。

AWS::ElastiCache::CacheCluster

以下がCacheClusterの設定例です。

  CacheCluster:
    Type: AWS::ElastiCache::CacheCluster
    Properties:
      AutoMinorVersionUpgrade: true
      Engine: redis
      EngineVersion: !Ref EngineVersion
      CacheNodeType: !Ref CacheNodeType
      CacheParameterGroupName: !Ref CacheParameterGroup
      CacheSubnetGroupName: !Ref CacheSubnetGroup
      Port: !Ref Port
      SnapshotRetentionLimit: !Ref SnapshotRetentionLimit 
      NumCacheNodes: !Ref NumCacheNodes
      VpcSecurityGroupIds:
        - !GetAtt CacheSecurityGroup.GroupId

これだけを見ると何も難しいところはなさそうです。CacheNodeTypeのノードがNumCacheNodes数だけ立ち上がるように見えますね。しかしながら、これを実行してクラスターを構築しようとするとNumCacheNodes should be 1 if engine is redisというエラーが出てStackの構築に失敗します。

原因は、エラーメッセージにあるとおりNumCacheNodesに1以外を設定したためです。NumCacheNodesという名前と直感的に反しますが、これは公式ドキュメントに書いてありました。

Redis 用 ElastiCache クラスターは、同じ役割を持つ 1 つまたは複数の Redis 用 ElastiCache ノードのコレクションです。プライマリノードはプライマリクラスター内に作成され、リードレプリカノードはリードレプリカクラスター内に作成されます。現在、1 つのクラスターは 1 つのノードのみを持つことができます。

つまり、現状1つのクラスターには1つのノードしか存在できないようです。

それではどうやってCloudFormationでElastiCacheのRedisクラスターを構築するかというと AWS::ElastiCache::ReplicationGroupテンプレートを使用します。

AWS::ElastiCache::ReplicationGroup

以下がAWS::ElastiCache::ReplicationGroupの実装例です。

  CacheReplicationGroup:
    Type: AWS::ElastiCache::ReplicationGroup
    Properties: 
      AutomaticFailoverEnabled: true
      CacheNodeType: !Ref CacheNodeType
      CacheParameterGroupName: !Ref CacheParameterGroup
      CacheSubnetGroupName: !Ref CacheSubnetGroup
      Engine: redis
      EngineVersion: !Ref EngineVersion
      NodeGroupConfiguration:
        - ReplicaCount: 1
      NumNodeGroups: 1 
      NumCacheClusters: 2 
      Port: !Ref Port
      ReplicasPerNodeGroup: !Ref NumCacheNodes 
      SecurityGroupIds:
        - !GetAtt CacheSecurityGroup.GroupId        
      SnapshotRetentionLimit: !Ref SnapshotRetentionLimit 

大体はなんとなくわかる気がするのですが、この中の4つのプロパティの違いがわからなくて混乱しました。以下はそのプロパティ名とAWS Documentの説明です。

  • NumNodeGroups
    • この Redis (clustered mode enabled) レプリケーショングループのノードグループ (シャード) の数。Redis (clustered mode disabled) では、このプロパティを省略します。
  • NumCacheClusters
    • このレプリケーショングループのキャッシュクラスターの数。自動フェイルオーバーが有効な場合、1 より大きな値を指定する必要があります。
  • ReplicasPerNodeGroup
    • 各ノードグループ(シャード)のレプリカノードの数
  • NodeGroupConfiguration: ReplicaCount:
    • ノードグループのリードレプリカノードの数

全部似たような説明で違いがよくわからなかったので、調べて見ました。

NumNodeGroups

NumNodeGroupsはRedis (clustered mode enabled) レプリケーショングループのノードグループ (シャード) の数を指定します。

クラスタモードが有効なRedisのレプリケーショングループの場合、一つのレプリケーショングループには複数のノードを集めたノードクラスタ(シャードを)含んでいるのでその数を指定するための項目のようです。 クラスタモードを無効にしてRedisで動作させたい場合はこのプロパティを省略します。

Redis用ElastiCacheに出てくる概念はこちらの記事が参考になりました。 ElastiCache + Redis に出てくる概念と、クラスタモードごとの違い

NumCacheClusters

NumCacheClustersレプリケーショングループのキャッシュクラスターの数です。 クラスタモードが無効の場合に設定します。 複数のシャードを指定(クラスタモード有効に)すると、このプロパティは無視されます。代わりに、ReplicasPerNodeGroup プロパティを使用するようです。

このプロパティと他の3つのプロパティは同時に指定することはできず、 指定してしまうと以下のようなエラーが出力されて構築に失敗します。

Property NumCacheCluster cannot be defined along with Properties
NumNodeGroups, ReplicasPerNodeGroup or NodeGroupConfiguration

ReplicasPerNodeGroup

各ノードグループ(シャード)のレプリカノードの数です。 こちらはNodeGroupConfigurationと同時には指定できません。 指定してしまうと以下のエラーが出ます。

Cannot specify both replicasPerNodeGroup and replicaCount.

NodeGroupConfiguration: ReplicaCount

NodeGroupConfigurationはノードグループの設定を指定するプロパティです。 レプリカ数だけでなく、アベイラビリティゾーンなどの設定も行えます。 ReplicaCountを指定することでノードグループのリードレプリカノード数を決めることができます。 このプロパティはクラスタモードが無効・有効どちらの場合でも使用できまが、 クラスタモードが有効(複数シャード)の場合は、シャード数分指定する必要があります。

      NumNodeGroups: 2
      NodeGroupConfiguration:
        - ReplicaCount: 1
        - ReplicaCount: 2

まとめ

  • AWS::ElastiCache::CacheClusterはひとつのノードだけ構築する際に使用する
  • AWS::ElastiCache::ReplicationGroupは複数のノードのクラスタを構築する際に使用する
    • クラスタモードが無効の場合(単一シャード)
      • NumCacheClustersかNodeGroupConfiguration: ReplicaCountを一つ指定する
    • クラスタモードが有効の場合(複数シャード)
      • NumNodeGroupsでシャード数を指定
      • ReplicasPerNodeGroupかNodeGroupConfiguration: ReplicaCountをシャード数分指定する

参考