AWS Lambdaから高解像度のカスタムメトリクスを出力
ConoHaに引き続き、再びインフラ方面。今回はAWSで。
AWS上にシステムを開発する中で「とあるLambda関数の起動回数を監視して、スケールアウト/インする」って感じの機能が欲しいなー、と作り込んでいた時のメモです。
CloudWatchメトリクス(アラーム)の間隔
CloudWatchでは、アラームを作成して閾値(5分間
に 関数が 5回
呼ばれたとか)を設定、それを超えたらAuto Scalingのアクションを発動! とかできます。ひとまず試しにLambda呼び出し回数のメトリクス(AWS/LambdaのInvocations)からアラームを作成してみると…なぜか監視間隔の10秒と30秒が選べないのが目に留まりました。
まぁ1分間隔でもいいんですが、今回の案件では極力早く検知 → スケールアウト開始したかったので、できれば使いたい。12回/60秒より、2回/10秒みたいな閾値のほうが細かく制御できそう…。で、調べてみると
- メトリクスは、デフォルトでは1分間隔での取得
- 1分未満のアラーム監視は高解像度(高分解能?)メトリクスを利用する
という2点がわかりました。
LambdaのNode.jsから高解像度メトリクスを出力する
標準で用意されているAWS/Lambda内のInvocationsを高解像度に設定すればいいの? とか考えて、調べるもよくわからず…(というか、そんな機能は存在しない?)
なので、対象のLambda関数から直接出力することにしました。単純に「適当な内容の高解像度メトリクスを投げる」という処理を追加しただけですが、起動回数がわかればいいのでこれで十分。
Lambdaのロール
CloudWatchにメトリクスを突っ込むので、Lambda関数のロールに "cloudwatch:PutMetricData"
を追加してあげてください。反映には少し時間がかかるかもしれません(?)
"Statement": [ { "Effect": "Allow", "Action": [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents", "cloudwatch:PutMetricData", ......... ..... ], "Resource": [ "*" ] } ]
例えばこんな感じでしょうか。
Node.js(6.10)から高解像度でメトリクス出力
該当部分のコードはこんな感じです。ここを参考にしつつとりあえず。
Class: AWS.CloudWatch — AWS SDK for JavaScript
var AWS = require('aws-sdk'); ..... ..... ..... // 利用するCloudWatchのリージョンを設定します AWS.config.region = event.region; ..... ..... ..... // CloudWatchメトリクス設定 const params = { MetricData: [ { MetricName: 'HiRes-Count', Dimensions: [ { Name: 'DimName', Value: 'DimValue' }, ], Timestamp: new Date(), Unit: 'Count/Second', Value: 1, // 高解像度指定 StorageResolution: 1 }, ], Namespace: 'ACJP/Lambda' }; // 実行 const cloudwatch = new AWS.CloudWatch(); cloudwatch.putMetricData(param, (err, data) => { if (err) { console.log(err, err.stack); // an error occurred } else { console.log(data); // successful response } }); ..... ..... .....
秒単位で関数の実行回数が取れればいいので、適当に Unit = 'Count/Second'
Value = 1
としています。ネームスペースやディメンション名はご自由に。
高解像度メトリクスにしたいので StorageResolution = 1
を忘れずに設定してあげます。
CloudWatchから確認
あとは適当に関数を実行して、メトリクスが出力されるのを待ちます。なんか、多少時間がかかったような気がします。
出力が成功していれば CloudWatch -> メトリクス
から参照できます。
これを使えば、10秒/30秒間隔のアラームも作成可能です。
イエー(少しだけ料金かかりますが)
ひとまずできました。あとはスケーリングのアクションを指定すればOKですね。
今回は高解像度のほうが良いので作ってみましたが、普通は分単位でいい気がするし、細かくログとるだけならどっかに投げれば? って感じもあり、自分としてはあんまり使わなさそう…かなぁ。
秒オーダー(または独自項目)のメトリクスが欲しい! アラームで使いたい! ダッシュボードに並べたい! などなどの場合は、カスタムメトリクスを使ってみるといいかもしれません。