
技術・機能解説、ノウハウ|AWS (構築・運用・コンサル)
AWS Lambda メモリ容量による処理性能の違い
こんにちは。伊藤忠テクノソリューションズ (以下、CTC) 丸山です。
AWS Lambdaの処理性能について調査した結果をご紹介します。
▼ 目次
・AWS Lambdaとは
・Lambdaでコードを実行するまで
・Lambdaのメモリ容量と処理能力の関係
1. AWS Lambdaとは
LambdaとはAWSが提供しているコンピュートサービスの1つで、イベントをきっかけとして、登録したコードを実行させることができます。”イベントをきっかけ”にして処理が走りますので、常時起動しているサーバが不要になるのが特徴です。

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つです。
- ランタイムを選ぶ
- コードを書く
- Lambdaに割り当てる権限を設定する
- メモリ容量を設定する
- タイムアウト時間を設定する
上記のステップ2以外は選択するだけですので、時間がかかることはありません。このように”本来やりたい処理”の作成にだけに時間を使えるのがLambdaを使うメリットの1つではないかと思います。また、何らかのリクエストによりLambdaが起動するように設定しておけば、リクエスト数に応じてスケールしていくので、アクセス数が予測できないような場合にも有効です。(そもそもリクエストが無ければ課金されませんので、お得です!)
利用料金に関しては、公式のアナウンスを参考にしていただければと思いますが、非常に安価にコードを実行することができます。また、毎月無償利用枠が設定されており(永久に有効らしいです)、ちょっとした検証作業や小規模アプリケーションで利用する場合には、無償枠内で収めることもできるかもしれません。
3. Lambdaのメモリ容量と処理能力の関係
コードを登録するだけで利用可能なLambdaですが、割り当てるMemory容量はどのように決定するのでしょうか?
私は当初、Lambdaを実行した際に使用されたメモリ容量で決定していました。実行時に使用されたメモリはLambdaの管理コンソールまたはCloudWatch Logsから確認することができます。
- Lambdaの管理コンソールで確認

- CloudWatch Logsで確認

上記の処理では 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)が割り当てメモリ容量に半比例していることが分かります。

したがって、”処理時間を短くしたい”という要件がある場合には、実際に使用されるメモリ容量を参考にするのではなく、大きなメモリ容量を割り当てるのが正解のようです。料金面から考えてみると、Lambdaは100ms毎の課金のため、今回の場合768MB以上の割り当てでは全て200msの課金がされることになります。同じ課金時間であれば、メモリ容量が増えることに比例して料金が増えていきますので、今回の場合では768MBが妥当な設定であるかと思います。
Memoryを1536MBを割り当て1回処理を実行した際の課金でも約$0.000025のため、大きな差とはなりませんし、そもそも検証であれば無償利用範囲で利用することもできますが、余計なリソースは割り当てないようにしたいですね。
- 関連記事のご案内
最後に
本記事では AWS Lambdaの処理性能について調査した結果をご紹介しました。APN プレミアコンサルティングパートナーの CTC は AWS のコンサルティング、設計、構築・運用までをワンストップでサポートするサービス『CUVIConAWS』をご提供しています。AWS の導入にあたってお困りの点があれば、お気軽にご相談頂けますと幸いです。サービスの詳細については以下をご覧下さい。