ElastiCache for Redis クラスターのクラスターモードが有効かどうかを一括で確認するワンライナー

長い人生、一度くらいはこんなコマンドを使いたい時があるかも知れません。

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

コンバンハ、千葉(幸)です。

ElastiCache for Redis ではクラスターモードが有効か無効か、という考え方があります。 Memcached も含めた大きな括りで考えると、以下のような区分けになるということです。

  • Redis (クラスターモード無効)
  • Redis (クラスターモード有効)
  • Memcached

Comparing Memcached and Redis - Amazon ElastiCache for Redis

複数ノードが存在する Redis クラスターであればそれすなわちクラスターモード有効、というわけではなくまた別の観点で確認する必要があります。

ひょんなことから、初めましての環境に複数存在するクラスターについてクラスターモードの有効/無効を確認したい機会があり、どうせなら一括でチェックしたかったのでワンライナーでやってみました。

同じことをしたい人が世界中で 20 人くらいはいると思うので参考になれば幸いです。

クラスターモードが有効かどうかを一括で確認するワンライナー

先にコマンドを載せておきます。お手元の端末や CloudShell などで実行してください。

% result=$(aws elasticache describe-cache-clusters --no-show-cache-clusters-not-in-replication-groups --output json) && echo $result | jq -r '["ノードID","パラメータグループ名"], (.CacheClusters[] | [.CacheClusterId, .CacheParameterGroup.CacheParameterGroupName]) | @csv' && echo "------------------------------------------" && echo '"パラメータグループ名","cluster-enabled"' && echo $result | jq -r '.CacheClusters[].CacheParameterGroup.CacheParameterGroupName' | sort | uniq | while read pgname; do aws elasticache describe-cache-parameters --cache-parameter-group-name $pgname --output json --query 'Parameters.{Value:[?ParameterName==`cluster-enabled`].ParameterValue}' | jq -r '["'$pgname'", .Value[]] | @csv'; done

実行することで、以下が表示されます。

  • クラスターの一覧とそれぞれに設定されているパラメータグループ
  • パラメータグループごとにパラメータcluster-enabledの値

内訳や詳細は後段で改めて取り上げます。

ElastiCache for Redis のクラスターモード

クラスターモードの有効/無効で何が違うのか、細かい差異はさまざまありますが一番の大きな違いはシャードを複数取りうるかどうかです。

以下の画像の左側がクラスターモード無効、右側が有効を表します。クラスターモードが無効な場合は単一のシャード構成となり、プライマリノードは全体で一つのみです。クラスターモードが有効な場合は最大 500 個までシャードを増やすことができ、それぞれのシャードにプライマリノードが存在します。

ElastiCache-NodeGroups

シャードが複数あることでデータを分割して処理でき、ボトルネックを回避したりより大きなデータセットに対応できるようになります。

シャードはマネジメントコンソールから参照するときは「シャード」ですが、API や CLI で扱うときには「ノードグループ」という名称で表されます。上記の画像でもノードグループという名称で表現されています。

無効/有効の比較表は以下の通りです。

機能 Redis (クラスターモードが無効) Redis (クラスターモードが有効)
変更可能 レプリカノードの追加と削除、ノードタイプのスケールアップをサポート 制限あり
データのパーティション化 いいえ はい
シャード 1 1 ~ 500
リードレプリカ 0 ~ 5 シャードあたり 0 ~ 5
マルチ AZ 一つ以上のレプリカが必要。オプション。デフォルトはオン 左に同じ
スナップショット (バックアップ) 1 つの .rdb ファイルを作成 シャードごとに独自の .rdb ファイルを作成
復元 Redis (クラスターモードが無効) クラスターから 1 つの .rdb ファイルを使用 Redis (クラスターモードが無効もしくは有効) クラスターから 1 つの .rdb ファイルを使用
サポート Redis のすべてのバージョン Redis 3.2 以降
エンジンアップグレード 可能だが制限あり 可能だが制限あり
Encryption バージョン 3.2.6 および 4.0.10 以降 バージョン 3.2.6 および 4.0.10 以降
HIPAA 適格 バージョン 3.2.6 および 4.0.10 以降 バージョン 3.2.6 および 4.0.10 以降
PCI DSS 準拠 バージョン 3.2.6 および 4.0.10 以降 バージョン 3.2.6 および 4.0.10 以降
オンラインリシャーディング 該当なし バージョン 3.2.10 以降

クラスターモードが有効か無効かはどのように確認するのか

ここまで確認した情報を整理すれば、クラスターモードの有効/無効が自明であるケースもあります。

  • エンジンが Memcached であれば無効(正確には「該当しない」)
  • バージョンが Redis 3.2 より古ければ無効
  • シャード(ノードグループ)が 2つ以上あれば有効

上記に当てはまらない場合はまた別の手段で確認します。

クラスターモードの有効/無効はクラスターそのものパラメータとして定義されているわけではなく、「クラスターに関連づけられているパラメータグループ内のパラメータ」で定義されています。

具体的には、cluster-enabledというパラメータです。この値がyes であれば有効、 noであれば無効です。こちらのエントリにて取り上げられています。

redis 3.2 以降のデフォルトパラメータグループでは末尾に.cluster.onという名称が付くものと付かないものが用意されており、両者の違いはcluster-enabledの値のみです。(.cluster.onが末尾につく方がyes。)デフォルトのパラメータグループを使用しているのであれば、末尾の名称を確認することでも判断できます。

ElastiCache_Management_Console_ParameterGroup

ともかく、クラスターモードの有効/無効を確認するには、クラスターに関連づけられているパラメータグループを確認しそのパラメータグループ内のcluster-enabledの値を確認する、というのをクラスターごとに実施していく必要があります。3 個程度ならマネジメントコンソールからやってもいいですが、それより多いとなかなか厳しいものがあります。

というわけで、ワンライナーの出番です。

ワンライナーでクラスターモードの有効/無効を一括で確認する

冒頭のコマンドを実行すると、以下のような形式で結果が出力されます。サンプルなので数が少ないですが、イメージは湧くかと思います。

% result=$(aws elasticache describe-cache-clusters --no-show-cache-clusters-not-in-replication-groups --output json) && echo $result | jq -r '["ノードID","パラメータグループ名"], (.CacheClusters[] | [.CacheClusterId, .CacheParameterGroup.CacheParameterGroupName]) | @csv' && echo "------------------------------------------" && echo '"パラメータグループ名","cluster-enabled"' && echo $result | jq -r '.CacheClusters[].CacheParameterGroup.CacheParameterGroupName' | sort | uniq | while read pgname; do aws elasticache describe-cache-parameters --cache-parameter-group-name $pgname --output json --query 'Parameters.{Value:[?ParameterName==`cluster-enabled`].ParameterValue}' | jq -r '["'$pgname'", .Value[]] | @csv'; done
"ノードID","パラメータグループ名"
"example","default.memcached1.6"
"hoge-001","default.redis6.x"
"hoge-002","default.redis6.x"
"hoge-003","default.redis6.x"
"sample-cluster-0001-001","default.redis6.x.cluster.on"
------------------------------------------
"パラメータグループ名","cluster-enabled"
"default.memcached1.6"
"default.redis6.x","no"
"default.redis6.x.cluster.on","yes"

下記の2種類の情報が、点線で区切られて出力されます。

  • クラスターの一覧とそれぞれに設定されているパラメータグループ
  • パラメータグループごとにパラメータcluster-enabledの値
    • ブランクかnoyesで、yes の場合のみクラスターモードが有効

ワンライナーを改行を挟んで説明すると、以下の構成になっています。

result=$(aws elasticache describe-cache-clusters\
  --no-show-cache-clusters-not-in-replication-groups --output json) &&\
echo $result | jq -r '["ノードID","パラメータグループ名"], (.CacheClusters[] | [.CacheClusterId, .CacheParameterGroup.CacheParameterGroupName]) | @csv' &&\
echo "------------------------------------------" &&\
echo '"パラメータグループ名","cluster-enabled"' &&\
echo $result | jq -r '.CacheClusters[].CacheParameterGroup.CacheParameterGroupName'\
  | sort | uniq | while read pgname; do
    aws elasticache describe-cache-parameters --cache-parameter-group-name $pgname --output json\
      --query 'Parameters.{Value:[?ParameterName==`cluster-enabled`].ParameterValue}'\
      | jq -r '["'$pgname'", .Value[]] | @csv'
  done

細部を省いて説明すると大まかに以下の処理を行なっています。

  • describe-cache-clustersでクラスター(ノード)一覧と関連づくパラメータグループ名を出力
  • パラメータグループの重複を排除してリスト化
  • リスト化したパラメータグループそれぞれに対してcluster-enabledの値を出力

AWS CLI コマンドについて補足します。

describe-cache-clusters

ハイライト部の値を取得しています。

{
    "CacheClusters": [
    {
            "CacheClusterId": "my-cluster-003",
            "ClientDownloadLandingPage": "https://console.aws.amazon.com/elasticache/home#client-download:",
            "CacheNodeType": "cache.r5.large",
            "Engine": "redis",
            "EngineVersion": "5.0.5",
            "CacheClusterStatus": "available",
            "NumCacheNodes": 1,
            "PreferredAvailabilityZone": "us-west-2a",
            "CacheClusterCreateTime": "2019-11-26T01:22:52.396Z",
            "PreferredMaintenanceWindow": "mon:17:30-mon:18:30",
            "PendingModifiedValues": {},
            "NotificationConfiguration": {
                "TopicArn": "arn:aws:sns:us-west-2:xxxxxxxxxxx152:My_Topic",
                "TopicStatus": "active"
            },
            "CacheSecurityGroups": [],
            "CacheParameterGroup": {
                "CacheParameterGroupName": "default.redis5.0",
                "ParameterApplyStatus": "in-sync",
                "CacheNodeIdsToReboot": []
            },
            "CacheSubnetGroupName": "kxkxk",
            "AutoMinorVersionUpgrade": true,
            "SecurityGroups": [
                {
                    "SecurityGroupId": "sg-xxxxxd7b",
                    "Status": "active"
                }
            ],
            "ReplicationGroupId": "my-cluster",
            "SnapshotRetentionLimit": 0,
            "SnapshotWindow": "06:30-07:30",
            "AuthTokenEnabled": false,
            "TransitEncryptionEnabled": false,
            "AtRestEncryptionEnabled": false,
            "ARN": "arn:aws:elasticache:us-west-2:xxxxxxxxxxx152:cluster:my-cache-cluster",
            "ReplicationGroupLogDeliveryEnabled": false,
            "LogDeliveryConfigurations": [
                {
                    "LogType": "slow-log",
                    "DestinationType": "cloudwatch-logs",
                    "DestinationDetails": {
                        "CloudWatchLogsDetails": {
                            "LogGroup": "test-log"
                        }
                    },
                    "LogFormat": "text",
                    "Status": "active"
                }
            ]
        }
    ]
}

このコマンドでは、ElastiCache for Redis に限って言えばノード単位で結果が出力されます。( Memcached の場合はクラスター単位での出力も可。)

--no-show-cache-clusters-not-in-replication-groupsオプションはあってもなくても特に影響はありません。先頭にno-がつかない--show-cache-clusters-not-in-replication-groupsオプションを使用すると、Memcached エンジンか単一ノードの Redis クラスターのみが返されます。(それらのみを抑止する、というオプションがあれば良かったのですがそういったものはありませんでした。)

describe-cache-parameters

パラメーターグループ内の各種パラメータが出力される中から、ParameterNamecluster-enabledもののParameterValueを引っ掛けています。

{
    "Parameters": [
....
				{
            "ParameterName": "cluster-enabled",
            "ParameterValue": "no",
            "Description": "Enable cluster mode",
            "Source": "user",
            "DataType": "string",
            "AllowedValues": "yes,no",
            "IsModifiable": true,
            "MinimumEngineVersion": "5.0.0",
            "ChangeType": "requires-reboot"
        },
....

jq だけでうまく出力する術が思いつかなかったので、フィルタリングは--queryオプションにて行っています。

    aws elasticache describe-cache-parameters --cache-parameter-group-name $pgname\
      --query 'Parameters.{Value:[?ParameterName==`cluster-enabled`].ParameterValue}'\
      | jq -r '["'$pgname'", .Value[]] | @csv'

これらのコマンドの組み合わせで一括取得を実現しています。

終わりに

ElastiCache for Redis クラスターのクラスターモードが有効かどうかを一括で確認するワンライナーのご紹介でした。

欲を言えば「ノード ID、パラメータグループ名、cluster-enabledの値」が一発で横並びになれば良かったのですが、わたしの jq 力ではうまくいきませんでした。

まぁそこまで頻繁に実行するものでもないからこのあたりがいい落とし所かな……ということでこの形になりました。もし機会があれば使ってあげてください。

以上、 チバユキ (@batchicchi) がお送りしました。