AWS Lambda メモリ容量による処理性能の違い

 こんにちは。伊藤忠テクノソリューションズ (以下、CTC) 丸山です。AWS Lambdaの処理性能について調査した結果をご紹介します。

1. AWS Lambdaとは

 LambdaとはAWSが提供しているコンピュートサービスの1つで、イベントをきっかけとして、登録したコードを実行させることができます。”イベントをきっかけ”にして処理が走りますので、常時起動しているサーバが不要になるのが特徴です。

AWS Lambdaとは

 2016年2月9日現在対応しているイベントとランタイムを調べてみました。

  • イベント
    • S3
    • DynamoDB
    • Kinesis
    • SNS
    • SES
    • Cognito Sync Trigger
    • CloudWatch Logs
    • CloudWatch Events
    • CloudWatch Events – Schedule
    • CloudFormation
    • AWS IoT

  • ランタイム
    • Node.js
    • Java
    • Python 2.7

2. Lambdaでコードを実行するまで

 ユーザがLambdaにより処理を行うために必要なステップは以下の5つです。

    1. ランタイムを選ぶ
    2. コードを書く
    3. Lambdaに割り当てる権限を設定する
    4. メモリ容量を設定する
    5. タイムアウト時間を設定する

 上記のステップ2以外は選択するだけですので、時間がかかることはありません。このように”本来やりたい処理”の作成にだけに時間を使えるのがLambdaを使うメリットの1つではないかと思います。また、何らかのリクエストによりLambdaが起動するように設定しておけば、リクエスト数に応じてスケールしていくので、アクセス数が予測できないような場合にも有効です。(そもそもリクエストが無ければ課金されませんので、お得です!)

 利用料金に関しては、公式のアナウンスを参考にしていただければと思いますが、非常に安価にコードを実行することができます。また、毎月無償利用枠が設定されており(永久に有効らしいです)、ちょっとした検証作業や小規模アプリケーションで利用する場合には、無償枠内で収めることもできるかもしれません。

3. Lambdaのメモリ容量と処理能力の関係

 コードを登録するだけで利用可能なLambdaですが、割り当てるMemory容量はどのように決定するのでしょうか?

 私は当初、Lambdaを実行した際に使用されたメモリ容量で決定していました。実行時に使用されたメモリはLambdaの管理コンソールまたはCloudWatch Logsから確認することができます。

  • Lambdaの管理コンソールで確認
AWS Lambdaとは
  • CloudWatch Logsで確認
AWS Lambdaとは

 上記の処理では Max Memory Usedが35MBとなっており、128MBで充分足りているのでしばらく128MBの設定のまま利用していました。しかし、もっと処理速度が速くならないかな?と思い、調査してみると、AWS Lambda開発者ガイドに以下の記載がありました。


Lambda 関数のコンピューティングリソース

Lambda 関数の作成時に、関数に割り当てたいメモリ量のみを選択します。次に、AWS Lambda は M3 タイプなど、汎用 Amazon EC2 インスタンスタイプと同じ割合を使用して、メモリに比例した CPU 能力を割り当てます。たとえば、256 MB を Lambda 関数に割り当てる場合、128 MB を割り当てた場合よりも 2 倍の CPU 共有が割り当てられます。


 書かれている通り、割り当てるメモリ容量により処理速度が違ってくるようです。どの程度違うのか気になったので、実際に測定してみました。実行するコードはDynamoDBに保存された1000件のアイテムをscanする処理としました。

console.log('*** Loading Lambda Func ***');

var AWS = require('aws-sdk');
var dynamo = new AWS.DynamoDB.DocumentClient({region: 'ap-northeast-1'});

var TABLE_NAME = 'SpecTest';

function scanTable(context) {
var params = {
TableName: TABLE_NAME
};
console.log('start: ' + context.getRemainingTimeInMillis());
dynamo.scan(params, function(err, res) {
if (err) {
console.log(err, err.stack);
context.succeed('*** scan fail ***');
} else {
console.log('end: ' + context.getRemainingTimeInMillis());
console.log('scan count: ' + res.Count);
context.succeed('*** scan complete ! ***');
}
});
}

exports.handler = function(event, context) {
scanTable(context);
};

コード説明

  • 4行目
    • AWS SDK for JavaScript の DynamoDB DocumentClientを使っています。
  • 12, 18行目
    • context.getRemainingTimeInMillis()でLambdaがTimeoutするまでの残り時間が取得できます。
  • 16行目
    • context.failとしてしまうと、Lambdaによりコードが再実行されてしまうため、context.succeedとし、”Lambdaの処理が完了した”という扱いにしています。


計測は3回実施し、その平均を取っています。グラフからわかるように、処理時間(Duration)が割り当てメモリ容量に半比例していることが分かります。

AWS Lambdaとは

 したがって、”処理時間を短くしたい”という要件がある場合には、実際に使用されるメモリ容量を参考にするのではなく、大きなメモリ容量を割り当てるのが正解のようです。料金面から考えてみると、Lambdaは100ms毎の課金のため、今回の場合768MB以上の割り当てでは全て200msの課金がされることになります。同じ課金時間であれば、メモリ容量が増えることに比例して料金が増えていきますので、今回の場合では768MBが妥当な設定であるかと思います。

 Memoryを1536MBを割り当て1回処理を実行した際の課金でも約$0.000025のため、大きな差とはなりませんし、そもそも検証であれば無償利用範囲で利用することもできますが、余計なリソースは割り当てないようにしたいですね。

最後に

 本記事では AWS Lambdaの処理性能について調査した結果をご紹介しました。APN プレミアコンサルティングパートナーの CTC は AWS のコンサルティング、設計、構築・運用までをワンストップでサポートするサービス『CUVIConAWS』をご提供しています。AWS の導入にあたってお困りの点があれば、お気軽にご相談頂けますと幸いです。サービスの詳細については以下をご覧下さい。

関連記事を読む

お問合せボタン

関連記事はこちら