メドピア開発者ブログ

集合知により医療を再発明しようと邁進しているヘルステックカンパニーのエンジニアブログです。読者に有用な情報発信ができるよう心がけたいので応援のほどよろしくお願いします。

監視にかかるコストを見直し半額にした話

SRE の田中 @kenzo0107 です。

メドピアグループでは主に AWS をプラットフォームとし、監視は Datadog で実施しています。

監視対象や課金対象のサービスの増加で徐々にコストが増加していたので、 利用状況を分析し、削減できる項目を調査しまとめました。

Datadog 子組織・サービス毎の利用料金の確認の仕方

親組織にある Usage & Cost > Individual Organizations *1 の Cost タブで各 org 毎の利用料金を確認できます。*2

事前に利用する量をコミット

www.datadoghq.com

事前に利用する量をコミットすることで 2~3割程、コスト削減できます。

ANNUALLY (年間でコミットを決定) の方がコスト削減率は高いですが、 MONTH-TO-MONTH (月毎にコミットを決定) を採用しています。

月毎に監視対象リソースの増減が頻繁にある為です。*3

Datadog APM のサンプルレートを下げる

Datadog APM の Ingested Span*4量は課金対象です。

docs.datadoghq.com

上記参考に Ingestion Control *5で Monthly Usage で使用量を確認し、 100% を超える分を冗長なデータとして取り込まない様にすることでコスト削減します。

サンプルレートを下げるコンテナの設定例

  • DD_APM_MAX_TPS = 1 とすることで 10 分の 1 で全体の 10% を取り込むように抑える
  • DD_APM_ENABLE_RARE_SAMPLER = true とし、稀に発生するサンプルを取りこぼさない様にする

Fargate タスク定義 JSON では以下の様になります。

{
    "name": "datadog",
    "image": "datadog/agent:latest",
    ...
    "environment": [
        {
            "name": "DD_APM_ENABLED",
            "value": "true"
        },
        {
            "name": "DD_APM_MAX_TPS",
            "value": "1"
        },
        {
            "name": "DD_APM_ENABLE_RARE_SAMPLER",
            "value": "true"
        }
    ],
    ...
}

Datadog APM EC2 vs Fargate

  • EC2 1 ホスト: 31 ドル / 月
  • Fargate 1 タスク: 2 ドル/月

既知の方は多いかと思いますが、念の為。
Fargate で Datadog APM を有効化した方が格段に安いです。

利用しない監視対象リソースのメトリクスを収集しない

  • 利用していないリージョンのメトリクス取得を無効化*6
  • 利用していない AWS サービスのメトリクス取得を無効化*7
  • EC2 のタグフィルターで datadog:true のタグを所持する EC2 のみ監視対象とする*8

Terraform で実装すると以下の通りです。

locals {
  enable_integration_list = [
    "application_elb",
    "elb",
  ]
}

resource "datadog_integration_aws" "this" {
  ...

  # 監視を有効化したいサービスのみ有効化する
  account_specific_namespace_rules = { for c in data.datadog_integration_aws_namespace_rules.rules.namespace_rules : c => contains(local.enable_integration_list, c) }

  # 除外リージョン
  excluded_regions = [
    "af-south-1",
    "ap-east-1",
    "ap-northeast-2",
    "ap-northeast-3",
    "ap-south-1",
    "ap-south-2",
    "ap-southeast-1",
    "ap-southeast-2",
    "ap-southeast-3",
    "ap-southeast-4",
    "ca-central-1",
    "ca-west-1",
    "eu-central-1",
    "eu-central-2",
    "eu-north-1",
    "eu-south-1",
    "eu-south-2",
    "eu-west-1",
    "eu-west-2",
    "eu-west-3",
    "il-central-1",
    "me-central-1",
    "me-south-1",
    "sa-east-1",
    "us-east-1",
    "us-east-2",
    "us-west-1",
    "us-west-2",
  ]

  # NOTE: メトリクスを収集する EC2 タグのフィルター設定
  #       datadog-agent インストール済みの EC2 のみ監視する為、以下タグをフィルターとする
  # see: https://registry.terraform.io/providers/DataDog/datadog/latest/docs/resources/integration_aws#optional
  filter_tags = ["datadog:true"]
}

data "datadog_integration_aws_namespace_rules" "rules" {}

上記対応により、 Datadog AWS Integration による AWS GetMetricData API の発行数が下がり、大幅にコスト削減できました。

AWS CloudWatch メトリクスで監視できるリソースは CloudWatch Alarm で監視

こちらも AWS GetMetricData API 発行コストを削減できます。

アラートの遅延*9を回避でき、副次的な効果がありました。

CloudWatch Alarm のリソースを監視する Terraform Module を作成し、監視の移行コストを下げました。

EC2 監視を Datadog Agent から CloudWatch Agent へ移行

Datadog の EC2 監視に掛かる Datadog Infrastructure Host のコストを削減したい意図です。

Datadog で監視していたメトリクスを CloudWatch Agent で取得し CloudWatch メトリクスに保存*10し、 CloudWatch Alarm でアラート発行する様にします。

CloudWatchAgent の設定ファイル例

{
    "agent": {
        "metrics_collection_interval": 60,
        "run_as_user": "root"
    },
    "metrics": {
        "aggregation_dimensions": [
            [
                "InstanceId"
            ]
        ],
        "append_dimensions": {
            "AutoScalingGroupName": "${aws:AutoScalingGroupName}",
            "ImageId": "${aws:ImageId}",
            "InstanceId": "${aws:InstanceId}",
            "InstanceType": "${aws:InstanceType}"
        },
        "metrics_collected": {
            "collectd": {
                "metrics_aggregation_interval": 60
            },
            "disk": {
                "measurement": [
                    "used_percent",
                    "inodes_free",
                    "inodes_total"
                ],
                "metrics_collection_interval": 60,
                "resources": ["*"]
            },
            "mem": {
                "measurement": ["mem_used_percent"],
                "metrics_collection_interval": 60
            },
            "statsd": {
                "metrics_aggregation_interval": 60,
                "metrics_collection_interval": 60,
                "service_address": ":8125"
            },
            "procstat": [
                {
                    "exe": "nginx",
                    "measurement": ["pid_count"],
                    "metrics_aggregation_interval": 60
                },
                {
                    "exe": "unicorn",
                    "measurement": ["pid_count"],
                    "metrics_aggregation_interval": 60
                }
            ]
        }
    }
}

以下カスタムメトリクスとして CloudWatch メトリクスに保存します。

  • ディスク使用率
  • ディスク i-node フリー
  • ディスク i-node トータル
  • メモリ使用率
  • procstat でプロセス監視

CPU 使用率はデフォルトで取得できるので設定していません。 inodes_free, inodes_total からディスク i-node 使用率を計算しています。

docs.aws.amazon.com

CloudWatch Agent に移行できないパターン

Datadog APM を利用している EC2 ホストは Datadog Agent を起動させておく必要があり、 CloudWatch Agent への移行ができません。*11

Datadog APM を有効化している EC2 ホストは CloudWatch Agent へ移行せず、移行できるものだけ移行することとしました。
監視設定が Datadog と AWS とハイブリッドになりますが、コスト削減メリットが大きく、移行を進めました。

通知内容自体も Datadog と CloudWatch Alarm で若干異なりますが、欲しい情報は取れていたので特段問題ありませんでした。*12

上記対応により、逐次 Datadog Infrastructure Host を削減できました。

過去 6 ヶ月の Datadog Infrastructure Host 利用量

Datadog に残したもの

代用できるサードパーティや自作する見通しが直ちに立たなかった為、元々使用していたものを利用することとしました。

まとめ

以下の対応により監視にかかるコストが年間 1 千万円ほど削減できました。

  • 事前に利用料をコミット
  • Datadog APM サンプルレートの適正化
  • 利用しない監視対象リソースのメトリクスを収集しない
  • AWS CloudWatch メトリクスで監視できるリソースは CloudWatch Alarm で監視
  • EC2 監視を Datadog Agent から CloudWatch Agent へ移行

全体的に監視を AWS に寄せたことが大きなコスト減の要因ですが、用法用量を適切に管理すること、サービスの知見を得ることで未然に意図しないコスト増を防ぐ必要があると改めて学びがありました。
怠惰に利用しない様、心に刻みます。

以上
参考になれば幸いです。


是非読者になってください


メドピアでは一緒に働く仲間を募集しています。 ご応募をお待ちしております!

■募集ポジションはこちら medpeer.co.jp

■エンジニア紹介ページはこちら engineer.medpeer.co.jp

■メドピア公式YouTube  www.youtube.com

■メドピア公式note
style.medpeer.co.jp

*1:Datadog ログイン後、親組織で admin 権限を持つアカウントのみアクセス可能です。

*2:プロジェクト毎の利用料金をわかりやすくすべく、 子組織に分けています。 メドピアグループでは terraform で Datadog リソースを管理しておりますが、terraform provider も子組織もサポートしています

*3:キャンペーンが多い月はサーバ数が増加したり、サービスがクローズした場合の影響度を下げる等、フレキシブルに変更可能にしたい意図です。毎月更新している訳ではなく、必要が生じた際に担当のカスタマーサポートに連絡し、変更いただいています。

*4:Ingested Span は、スタック内の個々のサービスに対する個別のリクエストです。Datadog に取り込まれたスパンのギガバイトの総数に基づき月末に課金されます。

Ingested Span = 上記図に見られる APM で取得 (Ingested) した各ブロック (Span)

参考: https://docs.datadoghq.com/ja/account_management/billing/apm_distributed_tracing/

*5:Datadog にログイン後に閲覧可能なリンクです。

*6:基本 ap-northeast-1, us-east-1 を利用しており、それ以外を除外しました。

Datadog AWS Integration の設定

*7:Datadog で利用したいメトリクス以外は無効化しました。

*8:タグフィルターを設定しないとデフォルトで全ての EC2 が監視対象となり、意図しないコスト増が発生します。

*9:docs.datadoghq.com

*10:CloudWatch のカスタムメトリクスを使用しましたが、いずれも無料枠で収まる量となりました。

*11:Datadog Agent, CloudWatch Agent 双方を起動させることは可能ですが、重複させる必要性はなく、Datadog Infrastructure Host の料金を下げる意図に反するので移行しませんでした。

*12:CloudWatch Alarm から Chatbot へポストし、 Slack 通知させています。