AWS Lambda+Node.jsのタイムアウト・メモリエラー時のコンテナ再利用の動作

2020-09-12
山下 徳光
#
AWS
#
Lambda
#

こんにちは、山下です。

以前検証した以下の記事のAWS Lambda+Node.jsのコンテナ再利用に関して、タイムアウト・メモリエラー時の再利用の動作を検証してなかったので再検証しました。

AWS Lambda+Node.jsのコンテナ並列起動(同期・非同期)・コンテナ再利用の動作検証 | グランドリーム

検証コードは GitHub にUPしてあるので、再検証など自由にご利用ください!

タイムアウト

Lambda実行がタイムアウトした場合の動作をみてみます。Lambdaのタイムアウトを1秒に設定して、次のように3秒スリープする処理を書きます。

"use strict";

const uuid = require("uuid");
const cid = uuid.v4();

module.exports.handle = async (event) => {
  console.log("START");
  console.log({ cid, pid: process.pid });
  await new Promise((resolve) => setTimeout(resolve, 3000));
  console.log("END");

  return { cid, pid: process.pid };
};

2回リクエストします。

$ sls invoke -f case6
{
    "errorMessage": "2020-09-12T02:35:56.903Z 5ca8dcb5-469d-434f-96cd-94c2fccf14a4 Task timed out after 1.00 seconds"
}

$ sls invoke -f case6
{
    "errorMessage": "2020-09-12T02:36:16.095Z 94f3e986-2a29-41c5-9204-df240c0b782e Task timed out after 1.00 seconds"
}

2回ともタイムアウトしました。ログをみてみましょう。

{ cid: '2e860385-3880-47ff-b16a-4da7f4688435', pid: 8 }
{ cid: '8141d50c-ec22-4957-9cd2-e55add38af29', pid: 7 }

コンテナIDが変化しています。

つまり、コンテナがタイムアウトすると、コンテナは再利用されないことがわかりました。

メモリエラー

Lambda実行でメモリエラーが発生した場合の動作をみてみます。次のようにメモリを無駄に消費する処理を書きます。

"use strict";

const uuid = require("uuid");
const cid = uuid.v4();

module.exports.handle = async (event) => {
  console.log("START");
  console.log({ cid, pid: process.pid });

  const buff = [];
  for (let i = 0; i < 1024 * 1024 * 128; i++) {
    buff.push(0);
  }

  console.log("END");

  return { cid, pid: process.pid };
};

2回リクエストします。

$ sls invoke -f case7
{
    "errorMessage": "RequestId: bfb98ac6-1185-428a-aadd-cc9eb56e83b8 Error: Runtime exited with error: signal: killed",
    "errorType": "Runtime.ExitError"
}

$ sls invoke -f case7
{
    "errorMessage": "RequestId: c1009725-2699-4a9a-ab65-394a3a745e9e Error: Runtime exited with error: signal: killed",
    "errorType": "Runtime.ExitError"
}

2回ともエラーになりました。ログをみてみましょう。

{ cid: '062c5b9d-b856-40e9-9f31-369ababe2fb9', pid: 8 }
{ cid: '459ef56f-af50-4497-aa1c-8e6e787f1aea', pid: 8 }

コンテナIDが変化しています。

つまり、コンテナでメモリエラーが発生すると、コンテナは再利用されないことがわかりました。

おわりに

Lambdaはグローバルオブジェクトの利用方法を制限していないからか、Lambda実行が正常終了しなかった場合、コンテナを再利用しないように設計されているようですね。さすがよくできてますね。

こんにちは、山下です。

以前検証した以下の記事のAWS Lambda+Node.jsのコンテナ再利用に関して、タイムアウト・メモリエラー時の再利用の動作を検証してなかったので再検証しました。

AWS Lambda+Node.jsのコンテナ並列起動(同期・非同期)・コンテナ再利用の動作検証 | グランドリーム

検証コードは GitHub にUPしてあるので、再検証など自由にご利用ください!

タイムアウト

Lambda実行がタイムアウトした場合の動作をみてみます。Lambdaのタイムアウトを1秒に設定して、次のように3秒スリープする処理を書きます。

"use strict";

const uuid = require("uuid");
const cid = uuid.v4();

module.exports.handle = async (event) => {
  console.log("START");
  console.log({ cid, pid: process.pid });
  await new Promise((resolve) => setTimeout(resolve, 3000));
  console.log("END");

  return { cid, pid: process.pid };
};

2回リクエストします。

$ sls invoke -f case6
{
    "errorMessage": "2020-09-12T02:35:56.903Z 5ca8dcb5-469d-434f-96cd-94c2fccf14a4 Task timed out after 1.00 seconds"
}

$ sls invoke -f case6
{
    "errorMessage": "2020-09-12T02:36:16.095Z 94f3e986-2a29-41c5-9204-df240c0b782e Task timed out after 1.00 seconds"
}

2回ともタイムアウトしました。ログをみてみましょう。

{ cid: '2e860385-3880-47ff-b16a-4da7f4688435', pid: 8 }
{ cid: '8141d50c-ec22-4957-9cd2-e55add38af29', pid: 7 }

コンテナIDが変化しています。

つまり、コンテナがタイムアウトすると、コンテナは再利用されないことがわかりました。

メモリエラー

Lambda実行でメモリエラーが発生した場合の動作をみてみます。次のようにメモリを無駄に消費する処理を書きます。

"use strict";

const uuid = require("uuid");
const cid = uuid.v4();

module.exports.handle = async (event) => {
  console.log("START");
  console.log({ cid, pid: process.pid });

  const buff = [];
  for (let i = 0; i < 1024 * 1024 * 128; i++) {
    buff.push(0);
  }

  console.log("END");

  return { cid, pid: process.pid };
};

2回リクエストします。

$ sls invoke -f case7
{
    "errorMessage": "RequestId: bfb98ac6-1185-428a-aadd-cc9eb56e83b8 Error: Runtime exited with error: signal: killed",
    "errorType": "Runtime.ExitError"
}

$ sls invoke -f case7
{
    "errorMessage": "RequestId: c1009725-2699-4a9a-ab65-394a3a745e9e Error: Runtime exited with error: signal: killed",
    "errorType": "Runtime.ExitError"
}

2回ともエラーになりました。ログをみてみましょう。

{ cid: '062c5b9d-b856-40e9-9f31-369ababe2fb9', pid: 8 }
{ cid: '459ef56f-af50-4497-aa1c-8e6e787f1aea', pid: 8 }

コンテナIDが変化しています。

つまり、コンテナでメモリエラーが発生すると、コンテナは再利用されないことがわかりました。

おわりに

Lambdaはグローバルオブジェクトの利用方法を制限していないからか、Lambda実行が正常終了しなかった場合、コンテナを再利用しないように設計されているようですね。さすがよくできてますね。

株式会社グランドリームでは、AWSを駆使した開発からUI/UXデザインまで、Webアプリケーションに関するすべての要望に応えます。
まずは一度お気軽にご相談ください。

お問い合わせはこちら