AWS Lambdaを使用して、SQLクエリを実行してRDS postgresデータベースからレコードを取得し、結果にSQSメッセージベースを作成する非常に単純なタスクを実行しました。pg-promiseを使用してAWS Lambdaの実行時間が長い理由
Amazonはデフォルトでノード4.3エンジンを使用しているaws-sdk
モジュールしか提供していないため、このSQLクエリを実行する必要があるため、pg-promise
を含むカスタム展開パッケージを作成する必要があります。
console.info('Loading the modules...');
var aws = require('aws-sdk');
var sqs = new aws.SQS();
var config = {
db: {
username: '[DB_USERNAME]',
password: '[DB_PASSWORD]',
host: '[DB_HOST]',
port: '[DB_PORT]',
database: '[DB_NAME]'
}
};
var pgp = require('pg-promise')({});
var cn = `postgres://${config.db.username}:${config.db.password}@${config.db.host}:${config.db.port}/${config.db.database}`;
if (!db) {
console.info('Connecting to the database...');
var db = pgp(cn);
} else {
console.info('Re-use database connection...');
}
console.log('loading the lambda function...');
exports.handler = function(event, context, callback) {
var now = new Date();
console.log('Current time: ' + now.toISOString());
// Select auction that need to updated
var query = [
'SELECT *',
'FROM "users"',
'WHERE "users"."registrationDate"<=${now}',
'AND "users"."status"=1',
].join(' ');
console.info('Executing SQL query: ' + query);
db.many(query, { status: 2, now: now.toISOString() }).then(function(data) {
var ids = [];
data.forEach(function(auction) {
ids.push(auction.id);
});
if (ids.length == 0) {
callback(null, 'No user to update');
} else {
var sqsMessage = {
MessageBody: JSON.stringify({ action: 'USERS_UPDATE', data: ids}), /* required */
QueueUrl: '[SQS_USER_QUEUE]', /* required */
};
console.log('Sending SQS Message...', sqsMessage);
sqs.sendMessage(sqsMessage, function(err, sqsResponse) {
console.info('SQS message sent!');
if (err) {
callback(err);
} else {
callback(null, ids.length + ' users were affected. SQS Message created:' + sqsResponse.MessageId);
}
});
}
}).catch(function(error) {
callback(error);
});
};
あなたはWatchLogsを見れば、私のラムダ関数をテスト、機能自体は実行に周りの500msかかったが、それはそれは実際30502.48ミリ秒を要したことを述べている(参照:スクリーンショット:ここでは私が使用しているコードがあります)。
だから私は私の318キロバイトパッケージを解凍し、それを実行を開始するために30秒を取っている推測していますか?私のためにはほんの冗談か何かが欠けている?私はzipをアップロードしようとしたが、私のパッケージをS3にアップロードして、それが速かったかどうかを確認したが、まだ同じレイテンシがある。私は本当にそれから離れて移動する必要はありませんので、私はPythonのバージョンがネイティブに任意のカスタムパッケージなしでSQL要求を実行できることに気づいた
が...
すべての私たちのアプリケーションはノードで書かれている、しかし、私が持っていますAmazonがデータベースとのやりとりのための基本的なnpmモジュールを提供していない理由を理解するのが難しい。
ご意見やご質問は歓迎します。この時点で私はLambdaが毎分トリガされるスクリプトを実行するのに30秒かかるなら、Lambdaが有益だろうと確信していません...
誰もが同じ問題に直面していますか?
UPDATE:これは、あなたが(彼の助けのためのヴィタリーに再び感謝)もうできるだけ早くあなたがそれを必要としないような接続をクローズする必要があるかです:
exports.handler = function(event, context, callback) {
[...]
db.many(query, { status: 2, now: now.toISOString() }).then(function(data) {
pgp.end(); // <-- This is important to close the connection directly after the request
[...]
30秒間の出現箇所を特定するためのログを追加してみてください。クエリ自体であるか、後で行うことであるかを特定してください。投稿した内容には正確性が十分ではありません。また、AWSは、言語の「標準」(およびAWS SDK)をサポートする各言語のランタイム環境を作成する傾向があります。 PythonはSQL標準を考慮していますが、JavaScriptはそうではありません。 –
おそらく予想を設定するのに関連しています:https://docs.aws.amazon.com/lambda/latest/dg/lambda-introduction-function.html#topic3 –
私はログを最初に持っています(最初の行は "データベースに接続しています" )そして最後に(cf. cloudwatchのスクリーンショットを参照)、私は自分のコードの実行時間が〜500ミリ秒であることを知っているか分かっています。請求されている30秒間は説明しません。あなたが提供したドキュメントを読んでも、この30秒間に何が起こっているのかは説明していません。解凍するのは時間ですか?コンテナを作成するには? – maxwell2022