本文へスキップ
hdknr blog
戻る

AWS DMS Serverless の OOM 障害と監視の盲点 — 検知漏れの根本原因と対策

AWS DMS Serverless Replication(CDC モード)が OOM(Out of Memory)で failed 状態になり、自動再起動の仕組みが検知できずに長期間停止していた問題について、根本原因と対策をまとめます。

構成

RDS (MySQL) → DMS Serverless (CDC) → S3 (Parquet)

発生した事象

症状

発覚の経緯

手動確認で発見。自動再起動 Lambda の最終実行は約2ヶ月前で、それ以降は検知されていなかった。

根本原因

原因 1: EventBridge ルールのイベントパターンが不完全

自動再起動用の EventBridge ルールが REPLICATION_TASK_STOPPED のみを監視していた。

{
  "source": ["aws.dms"],
  "detail-type": ["DMS Replication Task State Change"],
  "detail": {
    "eventType": ["REPLICATION_TASK_STOPPED"]
  }
}

DMS が OOM で異常終了した場合、イベントタイプは REPLICATION_TASK_STOPPED ではなく REPLICATION_TASK_FAILED として発火する。このため、EventBridge ルールがイベントをキャッチできず、Lambda による自動再起動も SNS 通知も行われなかった。

教訓: DMS の停止には「正常停止(stopped)」と「異常停止(failed)」の2種類がある。自動再起動を組む場合は両方を監視する必要がある。

原因 2: DMS Serverless の容量不足

max_capacity_units = 2(2 DCU)で全テーブル CDC を実行していたため、メモリが不足した。DMS Serverless はオートスケールするが、max_capacity_units が上限となるため、それを超えるワークロードでは OOM が発生する。

対策

1. EventBridge ルールの修正

REPLICATION_TASK_FAILED を追加し、異常停止も検知できるようにした。

{
  "detail": {
    "eventType": ["REPLICATION_TASK_STOPPED", "REPLICATION_TASK_FAILED"]
  }
}

2. DMS 容量の引き上げ

replication_config = {
  max_capacity_units = 4  # 2 → 4 に変更
  min_capacity_units = 2
}

3. 管理者へのメール通知(EventBridge → SNS)

DMS の停止/障害イベントを管理者にメールで通知する仕組みを追加。Lambda を経由せず、EventBridge → SNS トピック → メールの直接通知とした。

EventBridge Rule
  ├→ Lambda(自動再起動)
  └→ SNS Topic → Email(管理者通知)

Lambda を経由しない理由:

4. CloudWatch Alarm による予兆検知

OOM が発生する前に異常を検知するため、DMS Serverless のメトリクスに CloudWatch Alarm を設定。

アラームメトリクス閾値目的
*-dms-capacity-utilizationCapacityUtilization> 80%(15分間)OOM 予兆検知
*-dms-cdc-latency-sourceCDCLatencySource> 300秒(15分間)ソース遅延検知
*-dms-cdc-latency-targetCDCLatencyTarget> 300秒(15分間)ターゲット遅延検知
*-dms-cpu-utilizationCPUUtilization> 90%(15分間)CPU 高負荷検知

DMS Serverless の CloudWatch メトリクスでは MemoryUsage は提供されていないが、CapacityUtilization が全体的なリソース使用率を示すため、OOM の予兆検知に利用できる。

注意点: DMS Serverless の Dimension は ReplicationConfigId で、値の形式が {account_id}:{replication_config_identifier} となる(例: 726533500144:example-prod-dms)。通常の DMS のように ReplicationInstanceIdentifierReplicationTaskIdentifier ではないため、Terraform で動的に構成する場合は data.aws_caller_identity でアカウント ID を取得する必要がある。

Terraform 実装のポイント

SNS トピックポリシー

EventBridge と CloudWatch Alarms の両方から SNS に publish するため、トピックポリシーで両サービスを許可する。

data "aws_iam_policy_document" "sns_topic_policy" {
  # EventBridge からの publish
  statement {
    sid     = "AllowEventBridge"
    actions = ["sns:Publish"]
    principals {
      type        = "Service"
      identifiers = ["events.amazonaws.com"]
    }
    resources = [aws_sns_topic.dms_alert[0].arn]
    condition {
      test     = "ArnEquals"
      variable = "aws:SourceArn"
      values   = [aws_cloudwatch_event_rule.dms_stopped[0].arn]
    }
  }

  # CloudWatch Alarms からの publish
  statement {
    sid     = "AllowCloudWatchAlarms"
    actions = ["sns:Publish"]
    principals {
      type        = "Service"
      identifiers = ["cloudwatch.amazonaws.com"]
    }
    resources = [aws_sns_topic.dms_alert[0].arn]
    condition {
      test     = "StringEquals"
      variable = "aws:SourceAccount"
      values   = [data.aws_caller_identity.current[0].account_id]
    }
  }
}

条件付きリソース作成

通知機能はオプションのため、notification.enabled フラグで制御。

variable "notification" {
  type = object({
    enabled = bool
    email   = string
  })
  default = {
    enabled = false
    email   = ""
  }
}

監視体制の全体像(対策後)

DMS Serverless Replication

  ├─ [異常停止] EventBridge (STOPPED/FAILED)
  │    ├→ Lambda: 自動再起動(resume-processing)
  │    └→ SNS → Email: 管理者通知

  └─ [予兆検知] CloudWatch Alarms
       ├─ CapacityUtilization > 80%  → SNS → Email
       ├─ CDCLatencySource > 300s    → SNS → Email
       ├─ CDCLatencyTarget > 300s    → SNS → Email
       └─ CPUUtilization > 90%      → SNS → Email

まとめ

観点対策前対策後
異常停止の検知stopped のみstopped + failed
容量2 DCU(固定)2〜4 DCU(スケール可能)
管理者通知なしSNS メール通知
予兆検知なしCloudWatch Alarm(4メトリクス)

自動再起動の仕組みを作っても、検知するイベントが不完全だと意味がない。特に DMS のように stoppedfailed でイベントタイプが異なるサービスでは、障害パターンを網羅的にカバーすることが重要。また、障害発生後の対応だけでなく、CloudWatch Alarm による予兆検知を組み合わせることで、OOM のような致命的な障害を未然に防ぐことができる。



前の記事
mysqldump エラー 1449: DEFINER が存在しないユーザーを参照している場合の対処法
次の記事
Dexter: 約200行で動く自律型金融リサーチエージェント