5
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【AWS】LambdaからDynamoDBを呼ぶときは、タイムアウト時間を設定変更しようの巻

Posted at

起きたトラブル

APIGW <-> Lambda <-> DynamoDBのようなシンプルな構成で、DBの中身をサーバレス配信するようなAPIを作ったとき、ごくまれにLambdaがタイムアウトを起こした。Lambdaのランタイムはnodejs。

↓ランダムに大量リクエストを飛ばしてみると、全体の0.1%未満ながら、間違いなく5秒タイムアウトしている🤮
IMG_0106 3.JPG

Lambdaのタイムアウト時間は自由に設定変更できるが、30秒タイムアウトに設定しても改善しない。
(そもそも30秒もかかっていたら使い物にならないけど。)

なにがまずいのか

aws-sdkの仕様書より抜粋↓

timeout [Integer] — Sets the socket to timeout after timeout milliseconds of inactivity on the socket. Defaults to two minutes (120000).
(https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/DynamoDB.html#constructor-property)

JavaScript版のaws-sdkでは、DynamoDBのソケットタイムアウト時間がデフォルトで120000ms ( 2分間🤮 ) に設定されている。
すなわち、一度詰まってしまうと2分経過するまでDynamoDBへの通信をリトライしてくれない。
その結果、リトライ処理が呼ばれる前にLambdaがタイムアウトしてしまっていた。

こうなるとLambda内でエラーハンドルしていたとしても強制終了されてしまうため、ログにも現れないまま謎のタイムアウトとして処理されてしまう。

解決策

デフォルトで設定されているタイムアウト時間 (120000ms) を設定変更してやれば良い。
DynamoDBのDocumentClientを生成するタイミングでhttpOptionsとして引数を渡せば、デフォルト設定を上書きできる。
Lambdaのタイムアウト設定が5秒なら、ソケットタイムアウト200ms & リトライ上限10回くらいでちょうど良いのではないか(適当)。

sample.ts
import { DocumentClient } from 'aws-sdk/lib/dynamodb/document_client';

const dynamoClient: DocumentClient = new AWS.DynamoDB.DocumentClient({
  httpOptions: {
    timeout: 200,
  },
  maxRetries: 10,
});
5
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?