From 1bd53c38330bc481b74c27d6b9e07c1e18421532 Mon Sep 17 00:00:00 2001 From: Kouji Takao Date: Wed, 31 Dec 2025 23:54:26 +0900 Subject: [PATCH] feat: add DynamoDB metrics monitoring script MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added check-dynamodb-metrics.sh to monitor DynamoDB performance and detect throttling during load tests. Features: - Checks throttling (ThrottledRequests) - most important metric - Monitors consumed read/write capacity units - Detects system and user errors - Displays billing mode (on-demand vs provisioned) - Supports custom time ranges (default: past 1 hour) - macOS/Linux compatible date handling - Japanese language interface Updated README.md with: - DynamoDB Performance Monitoring section - Usage examples in Japanese - Troubleshooting guide for throttling issues - Table name discovery commands Usage: ./check-dynamodb-metrics.sh ./check-dynamodb-metrics.sh 2 # past 2 hours 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 --- test/load-test/README.md | 71 +++++++++++ test/load-test/check-dynamodb-metrics.sh | 148 +++++++++++++++++++++++ 2 files changed, 219 insertions(+) create mode 100755 test/load-test/check-dynamodb-metrics.sh diff --git a/test/load-test/README.md b/test/load-test/README.md index b719a7fc2b..a9f113a23c 100644 --- a/test/load-test/README.md +++ b/test/load-test/README.md @@ -149,6 +149,68 @@ Based on [GitHub Issue #68](https://github.com/smalruby/scratch-vm/issues/68): - **Error handling**: Comprehensive error logging and null-checking - **Metrics collection**: TPS, latency percentiles, event delivery tracking +## DynamoDB Performance Monitoring + +### Checking DynamoDB Metrics + +Use the provided script to check DynamoDB performance and throttling: + +```bash +# 基本的な使い方(過去1時間のメトリクスを確認) +./check-dynamodb-metrics.sh <テーブル名> + +# 過去2時間のメトリクスを確認 +./check-dynamodb-metrics.sh <テーブル名> 2 + +# 例:mesh-v2-groups-table の確認 +./check-dynamodb-metrics.sh mesh-v2-groups-table +``` + +### 確認項目 + +スクリプトは以下のメトリクスを自動的にチェックします: + +1. **スロットリング発生数** (ThrottledRequests) - 最重要 + - 期待値: 0(スロットリングなし) + - 0より大きい場合、キャパシティ不足を示す + +2. **読み込みキャパシティ消費量** (ConsumedReadCapacityUnits) + - 平均値と最大値を表示 + - 負荷テスト中の読み取り負荷を確認 + +3. **書き込みキャパシティ消費量** (ConsumedWriteCapacityUnits) + - 平均値と最大値を表示 + - 負荷テスト中の書き込み負荷を確認 + +4. **システムエラー** (SystemErrors) + - 期待値: 0 + - DynamoDB側の問題を示す + +5. **ユーザーエラー** (UserErrors) + - 期待値: 0または非常に少ない + - アプリケーション側のエラーを示す + +### テーブル名の確認方法 + +```bash +# 利用可能なDynamoDBテーブル一覧を表示 +aws dynamodb list-tables --output table + +# CloudFormationスタックからテーブル名を取得 +aws cloudformation describe-stacks \ + --stack-name <スタック名> \ + --query 'Stacks[0].Outputs[?OutputKey==`GroupsTableName`].OutputValue' \ + --output text +``` + +### オンデマンドモードの確認 + +スクリプトは自動的に課金モードを表示します。期待される出力: + +``` +BillingMode: PAY_PER_REQUEST +``` + ## Troubleshooting ### Error: "maxConnectionTimeSeconds cannot exceed 600" @@ -163,6 +225,15 @@ Groups require periodic heartbeats. The implementation automatically sends an in If tests are reusing the same domain name, stale groups may cause conflicts. The tests now use unique domain names per run: `test-domain-${Date.now()}` +### DynamoDB Throttling Detected + +If `check-dynamodb-metrics.sh` reports throttled requests: + +1. Check if on-demand mode is enabled (should be `PAY_PER_REQUEST`) +2. Review the load pattern - sudden spikes may cause temporary throttling +3. Consider implementing exponential backoff in client code +4. Check AWS Service Quotas for DynamoDB limits + ## Report Generation Generate a Markdown report from test results: diff --git a/test/load-test/check-dynamodb-metrics.sh b/test/load-test/check-dynamodb-metrics.sh new file mode 100755 index 0000000000..dba9d5efc3 --- /dev/null +++ b/test/load-test/check-dynamodb-metrics.sh @@ -0,0 +1,148 @@ +#!/bin/bash +# DynamoDB メトリクス確認スクリプト +# MESH v2 負荷テスト用 - DynamoDBのスロットリングとパフォーマンスを確認 + +set -e + +TABLE_NAME="${1:-}" +HOURS_AGO="${2:-1}" + +if [ -z "$TABLE_NAME" ]; then + echo "使用方法: $0 <テーブル名> [時間前(デフォルト:1)]" + echo "" + echo "例:" + echo " $0 mesh-v2-groups-table # 過去1時間のメトリクスを表示" + echo " $0 mesh-v2-groups-table 2 # 過去2時間のメトリクスを表示" + echo "" + echo "利用可能なテーブル一覧:" + aws dynamodb list-tables --query 'TableNames' --output table 2>/dev/null || echo " (AWS CLIでテーブル一覧を取得できませんでした)" + exit 1 +fi + +# macOS/Linux 互換の日付計算 +if date --version >/dev/null 2>&1; then + # GNU date (Linux) + START_TIME=$(date -u -d "$HOURS_AGO hours ago" +"%Y-%m-%dT%H:%M:%SZ") + END_TIME=$(date -u +"%Y-%m-%dT%H:%M:%SZ") +else + # BSD date (macOS) + START_TIME=$(date -u -v-${HOURS_AGO}H +"%Y-%m-%dT%H:%M:%SZ") + END_TIME=$(date -u +"%Y-%m-%dT%H:%M:%SZ") +fi + +echo "=========================================" +echo "DynamoDB メトリクス確認" +echo "=========================================" +echo "テーブル名: $TABLE_NAME" +echo "期間: $START_TIME ~ $END_TIME" +echo "=========================================" +echo "" + +# テーブルの課金モードを確認 +echo "【課金モード】" +aws dynamodb describe-table \ + --table-name "$TABLE_NAME" \ + --query 'Table.BillingModeSummary' \ + --output table 2>/dev/null || echo " テーブル情報を取得できませんでした" +echo "" + +# 1. スロットリング確認(最重要) +echo "【1. スロットリング発生数】★最重要★" +echo " 期待値: 0 (スロットリングが発生していないこと)" +THROTTLED=$(aws cloudwatch get-metric-statistics \ + --namespace AWS/DynamoDB \ + --metric-name ThrottledRequests \ + --dimensions Name=TableName,Value="$TABLE_NAME" \ + --start-time "$START_TIME" \ + --end-time "$END_TIME" \ + --period 300 \ + --statistics Sum \ + --query 'Datapoints[*].[Timestamp,Sum]' \ + --output table 2>/dev/null) + +if [ -z "$THROTTLED" ] || echo "$THROTTLED" | grep -q "None"; then + echo " ✅ データなし(スロットリングなし)" +else + echo "$THROTTLED" + # スロットリングがあるか確認 + if echo "$THROTTLED" | grep -q "|.*[1-9]"; then + echo " ⚠️ 警告: スロットリングが発生しています!" + else + echo " ✅ スロットリングなし" + fi +fi +echo "" + +# 2. 読み込みキャパシティ +echo "【2. 読み込みキャパシティ消費量】" +aws cloudwatch get-metric-statistics \ + --namespace AWS/DynamoDB \ + --metric-name ConsumedReadCapacityUnits \ + --dimensions Name=TableName,Value="$TABLE_NAME" \ + --start-time "$START_TIME" \ + --end-time "$END_TIME" \ + --period 300 \ + --statistics Average,Maximum \ + --query 'Datapoints[*].[Timestamp,Average,Maximum]' \ + --output table 2>/dev/null || echo " データなし" +echo "" + +# 3. 書き込みキャパシティ +echo "【3. 書き込みキャパシティ消費量】" +aws cloudwatch get-metric-statistics \ + --namespace AWS/DynamoDB \ + --metric-name ConsumedWriteCapacityUnits \ + --dimensions Name=TableName,Value="$TABLE_NAME" \ + --start-time "$START_TIME" \ + --end-time "$END_TIME" \ + --period 300 \ + --statistics Average,Maximum \ + --query 'Datapoints[*].[Timestamp,Average,Maximum]' \ + --output table 2>/dev/null || echo " データなし" +echo "" + +# 4. システムエラー +echo "【4. システムエラー】" +echo " 期待値: 0" +SYSTEM_ERRORS=$(aws cloudwatch get-metric-statistics \ + --namespace AWS/DynamoDB \ + --metric-name SystemErrors \ + --dimensions Name=TableName,Value="$TABLE_NAME" \ + --start-time "$START_TIME" \ + --end-time "$END_TIME" \ + --period 300 \ + --statistics Sum \ + --query 'Datapoints[*].[Timestamp,Sum]' \ + --output table 2>/dev/null) + +if [ -z "$SYSTEM_ERRORS" ] || echo "$SYSTEM_ERRORS" | grep -q "None"; then + echo " ✅ データなし(エラーなし)" +else + echo "$SYSTEM_ERRORS" +fi +echo "" + +# 5. ユーザーエラー +echo "【5. ユーザーエラー】" +echo " 期待値: 0 または 非常に少ない" +USER_ERRORS=$(aws cloudwatch get-metric-statistics \ + --namespace AWS/DynamoDB \ + --metric-name UserErrors \ + --dimensions Name=TableName,Value="$TABLE_NAME" \ + --start-time "$START_TIME" \ + --end-time "$END_TIME" \ + --period 300 \ + --statistics Sum \ + --query 'Datapoints[*].[Timestamp,Sum]' \ + --output table 2>/dev/null) + +if [ -z "$USER_ERRORS" ] || echo "$USER_ERRORS" | grep -q "None"; then + echo " ✅ データなし(エラーなし)" +else + echo "$USER_ERRORS" +fi +echo "" + +echo "=========================================" +echo "確認完了" +echo "========================================="