必要な環境
下記環境が必要になりますのであらかじめインストールしてください
- aws cli
- jq
従来の問題点
kinesis の describe-stream コマンドだと、JSONがどばーってでてきて、現在有効なshardId がひと目でわからないといった問題がありました
下記が例です。この例だと、shardId-000000000003 以外は、データレコードを put できない shard なのですが、わからないですよね!(close な shard は、shard の分割、マージによって発生します)
aws kinesis describe-stream --stream-name <ストリーム名>
{
"StreamDescription": {
"StreamStatus": "ACTIVE",
"StreamName": "<ストリーム名>",
"StreamARN": "arn:aws:kinesis:ap-northeast-1:XXXXXXXXXXXX:stream/handson",
"Shards": [
{
"ShardId": "shardId-000000000000",
"HashKeyRange": {
"EndingHashKey": "340282366920938463463374607431768211455",
"StartingHashKey": "0"
},
"SequenceNumberRange": {
"EndingSequenceNumber": "49550864092662459711139433817050545721599481607404650498",
"StartingSequenceNumber": "49550864092651309338540168505480986788282674130572017666"
}
},
{
"ShardId": "shardId-000000000001",
"HashKeyRange": {
"EndingHashKey": "170141183460469231731687303715884105727",
"StartingHashKey": "0"
},
"ParentShardId": "shardId-000000000000",
"SequenceNumberRange": {
"EndingSequenceNumber": "49550864601498562906012662037471029548617289644346703890",
"StartingSequenceNumber": "49550864601487412533413396725901470615300436606500995090"
}
},
{
"ShardId": "shardId-000000000002",
"HashKeyRange": {
"EndingHashKey": "340282366920938463463374607431768211455",
"StartingHashKey": "170141183460469231731687303715884105728"
},
"ParentShardId": "shardId-000000000000",
"SequenceNumberRange": {
"EndingSequenceNumber": "49550864601520863651211192660612565266889938005852684322",
"StartingSequenceNumber": "49550864601509713278611927349043006333573084968006975522"
}
},
{
"ShardId": "shardId-000000000003",
"HashKeyRange": {
"EndingHashKey": "340282366920938463463374607431768211455",
"StartingHashKey": "0"
},
"ParentShardId": "shardId-000000000001",
"AdjacentParentShardId": "shardId-000000000002",
"SequenceNumberRange": {
"StartingSequenceNumber": "49550865346912121539498005854874389596844711860389281842"
}
}
]
}
}
解決策
そこでワンライナー作りました。
出力されるjsonを加工して、あとは awk でこねくり回しています。
STREAM_NAME=<ストリーム名>
aws kinesis describe-stream --stream-name ${STREAM_NAME} | jq -r '.StreamDescription | .Shards[] | "\(.ShardId) \(.ParentShardId) \( .AdjacentParentShardId) \(.HashKeyRange | .StartingHashKey)"' | sed s/shardId-//g |awk 'BEGIN{i=0;print}{hashKey[i]=$4;state[i]="Open";if($2 != "null"){state[$2/1]="Close"};if($3 != "null"){state[$3/1]="Close"};i++}END{for(j=0;j<i;j++) printf("shardId-%012d %5s start: %s\n",j,state[j],hashKey[j]);}'
出力結果は下記のような感じ。
左からshardId, 現在有効/無効なshardはOpen/close、"Start: 数値"は shardの "StartingHashKeyを表しています
shardId-000000000000 Close Start: 0
shardId-000000000001 Close Start: 0
shardId-000000000002 Close Start: 170141183460469231731687303715884105728
shardId-000000000003 Open Start: 0
ぜひ使ってくださいね!
シェルスクリプト
上記だと分かりにくいので、一応スクリプト化しておきます。
"ParentShardId" もしくは "AdjacentParentShardId" に書かれているShardIdはすでに close されています。この性質を利用して、Open、か Closeを判定しています。shardIdの"Id"のみを抜き出して、state 配列の Index に入れることがポイントです
アルゴリズムの詳細は下記 3STEP です。
- Shardのステータスを保持する
state[i]
に対し、まず、Open で 初期化する - "ParentShardId" もしくは "AdjacentParentShardId" が あれば、そのShardIdの"数字のみ"を取得する(例:shardId-000000000001なら、"1")
- 取得した数字を Shardのステータスを保持するstate配列のIndexに入れ、値を Open から Close に上書きする(state[$2/1]のように1で割っているのは強引にInt型にキャストするため)
#!/bin/bash
STREAM_NAME=$1
#
# open/close 判定
#
shardChecker()
{
awk '
BEGIN{
i=0;
printf("\n");
}
{
hashKey[i]=$4;
state[i]="Open";
if($2 != "null"){state[$2/1]="Close"};
if($3 != "null"){state[$3/1]="Close"};
i++;
}
END{
for(j=0;j<i;j++) {
printf("shardId-%012d %5s start: %s\n",j,state[j],hashKey[j]);
}
}'
}
#
# main
#
aws kinesis describe-stream --stream-name ${STREAM_NAME} \
| jq -r '.StreamDescription | .Shards[] | "\(.ShardId) \(.ParentShardId) \( .AdjacentParentShardId) \(.HashKeyRange | .StartingHashKey)"'\
| sed s/shardId-//g \
| shardChecker