Knex: AWS LambdaでKnexを䜿甚するにはどうすればよいですか

䜜成日 2017幎01月20日  Â·  34コメント  Â·  ゜ヌス: knex/knex

いく぀かのコヌドをテストしおいるずきに、接続プヌルで問題が発生しおいたす。 ラムダ関数が数秒間に数千回呌び出されるこずを期埅しおおり、デヌタベヌスに接続するための最良の方法を芋぀けるのに苊劎しおいたす。 ここでは非垞に䌌おいたす問題ノヌド/ postgresのために基本的に問題は1぀が利甚可胜な堎合、私はしかし、私はので、どのようにAWS圓おにならずに再利甚、既存のプヌルに䟝存するこずはできたせん、プヌルから接続を取埗できるようにする必芁があるずいうこずですラムダコンテナ。

基本的に私が探しおいるのは、デヌタベヌスぞの接続を確実に取埗たたは䜜成する方法です。 䟋を芋぀けるこずができたせんでした while(!availableConnections) { tryToGetConnection() } 。 node-poolず察話する必芁がありたすかKnexでこれを行うにはどうすればよいですか

insightful question

最も参考になるコメント

申し蚳ありたせんが、文の途䞭でコミットしたした。私の子䟛は3リットルの氎を床に投げたした1st_place_medal䞊蚘のコメントをすぐに曎新したす...

党おのコメント34件

Knexプヌリングは、接続が同じノヌドプロセスから行われる堎合にのみ機胜したす。

AWSラムダむンスタンスが共有ノヌドプロセスを実行しおいない堎合は、各ラムダむンスタンスに最小/最倧接続1の新しいプヌルを䜜成する必芁があり、デヌタベヌスに数癟の同時接続を蚱可するのに十分な蚭定があるこずを期埅したすRDSではむンスタンスサむズによっお異なりたす 。

これを読んだ埌https://forums.aws.amazon.com/thread.jspa?threadID=216000

ラムダは実際にいく぀かのプロセスを共有しおいるように芋えるので、䜜成されたラムダコンテナヌの最倧数を把握できれば、最適なプヌルサむズを蚈算できるはずです各コンテナヌには個別のプヌルがあるため、DBぞの接続の合蚈はプヌルになりたす。 max *最倧コンテナ数。

ずにかく、プヌルから手動で接続を芁求する必芁はありたせん。knexは自動的に接続を埅機し、数秒ですべおが終了した堎合、その時間内にタむムアりトがトリガヌされるこずはありたせん。

最倧接続数に達したこずを瀺す゚ラヌがDBから発生する堎合は、最倧プヌルサむズを小さくする必芁がありたす。

申し蚳ありたせんが、文の途䞭でコミットしたした。私の子䟛は3リットルの氎を床に投げたした1st_place_medal䞊蚘のコメントをすぐに曎新したす...

返信いただきありがずうございたす。 接続数は時間の経過ずずもに倧幅に倉化したすが、最倧プヌルサむズを芋積もるこずが最善の策のようです。

明確にするために、Knexで接続を閉じる方法はありたせんよね 接続プヌルを砎棄する機胜のみですか Lambdaがコンテナを再利甚するこずがあるずいう事実は、すべおを捚おおしたいたす。

接続プヌルを砎棄するず、すべおの接続も砎棄され最初に完了するのを優雅に埅機したす、ラムダがコンテナヌを砎棄するず、プロセスが終了するず、開いおいるすべおのTCP゜ケットが暗黙的に閉じられるず思いたす。

プヌリングの利点が倱われるため、各リク゚ストの埌に明瀺的に接続を閉じようずする必芁がある理由がわかりたせん。 サむズ1のプヌルを䜜成し、埌で砎棄しおも同じ効果が埗られたす。

プヌルのアむドルタむムアりトを構成するこずもできたす。これは、䜿甚されおおらず、プヌルでのアクションを埅機しおいる堎合に接続を自動的に閉じたす。

Knexを䜿甚しおCOPYク゚リをRedShiftクラスタヌに送信し、結果を埅たないこずはできたすか

pg Poolでこれを行うず、Lambda関数の終わりに達するずすぐにク゚リが終了したす。

@BardiaAfshinラムダ関数の終了に達したずきにラムダコンテナが砎棄され、そのすべおの゜ケットが解攟された堎合、dbク゚リも終了し、終了しない可胜性がありたす。

結果倀を読み取る前に暗黙のトランザクションが終了しおいないためにCOPYク゚リがロヌルバックされる堎合、postgresqlがクラむアント偎の接続の終了にどのように反応するかはわかりたせん...

ずにかく、ク゚リを送信できるかどうかはknex次第ではありたせんが、awslambdaずpostgresqlがどのように機胜するかによっお異なりたす。

私の芳察では、ク゚リはRedShiftで匷制終了され、ロヌルバックされたす。

ずにかく、プヌルから手動で接続を芁求する必芁はありたせん。knexは自動的に接続を埅機し、数秒ですべおが終了した堎合、その時間内にタむムアりトがトリガヌされるこずはありたせん。

デヌタベヌス負荷テストスクリプトを実行しおいたすが、これは正しくないようです。 30の同時接続のようなものより高いものは、開いおいる接続を埅぀のではなく、すぐにタむムアりトしたす。

ク゚リが実行されたら、珟圚䜿甚されおいる接続を手動で解攟する方法はありたすか

AWS Lambdaを始めたばかりの私たちのために共有できるサンプルコヌドを誰かが持っおいたすか 誰かがknex / postgres / lambdaのパタヌンやアンチパタヌンを共有できるこずを願っおいたす。

これが私が今䜿っおいるものです-それは改善できるず確信しおいたすが、私が正しい道を進んでいるかどうかに぀いお少しの蚌拠を期埅しおいたす...

'use strict';
var pg = require('pg');

function initKnex(){
  return require('knex')({
      client: 'pg',
      connection: { ...details... }
  });
}

module.exports.hello = (event, context) =>
{
  var knex = initKnex();

  // Should I be returning knex here or in the final catch?
  knex
  .select('*')
  .from('my_table')
  .then(function (rows) {
    context.succeed('Succeeded: ' + JSON.stringify(rows || []));
  })
  .catch(function (error) {
    context.fail(error);
  })
  .then(function(){
    // is destroy overkill? - is there an option for knex.client.release, etc?
    knex.destroy();
  })
}

私は同じ船に乗っおいたす-たくさんのグヌグルずテストにもかかわらず、ただ最善の方法が䜕であるかを理解しおいたせん。 私が今しおいるこずは

const dbConfig = require('./db');
const knex = require('knex')(dbConfig);

exports.handler = function (event, context, callback) {
...
connection = {..., pool: { min: 1, max: 1 },

このようにしお、接続コンテナヌごずに最倧1぀が維持されるため、コンテナヌを簡単に再利甚できたす。 私は最埌に私の接続を砎壊したせん。

http://blog.rowanudell.com/database-connections-in-lambda/

これが最善の方法かどうかはわかりたせんが、これたでのずころうたくいきたした。

/肩をすくめる

@austingayler

const knexが宣蚀されたずきに䜕が起こるか正確にはわかりたせん-これは初期接続がセットアップされる堎所ですか 誰かが明確にするこずができたすか dbConfigに接続情報があるず想定しおいたす

あなたのコヌドでは、ハンドラヌが呌び出されるたびに接続自䜓が䞊曞きされお再䜜成されおいたせんか

同じボヌトに乗っおいる人にチャむムを鳎らしおいるだけで、コンテナずプヌルのサむズを比范するのにあたり運がありたせんでした

const knex = require('knex');

const client = knex(dbConfig);

client(tableName).select('*')
  .then((result) => { 

    return Promise.all([
      result,
      client.destroy(),
    ])  
  })
  .then(([ result ]) => {

    return result;
  });

TL; DRコヌルバックを呌び出す前にcontext.callbackWaitsForEmptyEventLoop = false蚭定するだけです。

AWS Lambdaは、空のむベントルヌプを埅機したすデフォルト。 そのため、コヌルバックが実行されおも、関数はタむムアりト゚ラヌをスロヌする可胜性がありたす。

詳现に぀いおは、以䞋のリンクを参照しおください。
https://github.com/apex/apex/commit/1fe6e91a46e76c2d5c77877be9ce0c206e9ef9fb

@elhigu @tgriesserぞこれはknexの問題ではありたせん。 これは間違いなくラムダ環境の問題です。 私はこの問題に質問のタグを付けお、閉じるのが良いず思いたす:)

@mooyoulうん、間違いなくknexの問題ではないが、ドキュメントの問題かもしれない... knexdocsにawslambda固有のものは必芁ないず思うので、閉じたす。

このリンクを芋おください
https://stackoverflow.com/questions/49347210/why-aws-lambda-keeps-timing-out-when-using-knex-js
db接続を閉じる必芁がありたす。そうしないず、Lambdaがタむムアりトするたで実行されたす。

KnexをLambdaで䜿甚するために完璧に機胜するパタヌンを芋぀けた人はいたすか

接続を正しく閉じたずきに他に問題がありたすか

私が避けようずしおいるのは、接続を閉じお、ラムダの呌び出し党䜓で利甚できるようにするこずです。

Lambdaが呌び出し間の状態の維持を蚱可したすか

https://scalegrid.io/blog/how-to-use-mongodb-connection-pooling-on-aws-lambda/のnode.jsの郚分を確認しお

私はこのようにスレッドをぶ぀けるのは奜きではありたせんが、コメントで倱われおいるず思うので、䞊蚘の@mooyoulの答えは私たちにずっおうたくいきたした。

そのフラグをfalseにしないず、Lambdaはむベントルヌプが空になるのを埅ちたす。 そうした堎合、コヌルバックを呌び出すずすぐに関数は実行を終了したす。

私にずっおは、ロヌカルマシンでは機胜したしたが、デプロむ埌は機胜したせんでした。 私はちょっず誀解を招きたした。

RDSむンバりンド゜ヌスが私のLambda関数に察しお開かれおいないこずがわかりたした。 Stack Overflowで解決策が芋぀かりたしたRDSむンバりンド゜ヌスを0.0.0.0/0か、VPCを䜿甚したす。

RDSむンバりンド゜ヌスを曎新した埌、KnexでLambdaを正垞に実行できたす。

私が䜿甚しおいるLambdaランタむムはNode.js 8.10 、パッケヌゞは次のずおりです。

knex: 0.17.0
pg: 7.11.0

非同期を䜿甚する以䞋のコヌドも機胜したす

const Knex = require('knex');

const pg = Knex({ ... });

module.exports. submitForm = async (event) => {
  const {
    fields,
  } = event['body-json'] || {};

  return pg('surveys')
    .insert(fields)
    .then(() => {
      return {
        status: 200
      };
    })
    .catch(err => {
      return {
        status: 500
      };
    });
};

うたくいけば、それは将来同じ問題に遭遇するかもしれない人々を助けるでしょう。

私が人々の泚意を匕きたいのは、 serverless-mysqlパッケヌゞです。これは、暙準のmysqlドラむバヌをラップしたすが、このスレッドで説明されおいる接続プヌル管理に関するラムダ固有の問題点の倚くを凊理したす。

ただし、別のドラむバヌに亀換する方法がないため、珟時点ではこの問題によるずKnexがserverless-mysqlで動䜜するずは思いたせん。 serverless-mysqlはコヌルバックの代わりにpromiseを䜿甚するため、非互換性も存圚する可胜性がありたす。

最善のアプロヌチは、おそらくKnexに新しいクラむアント実装を远加するこずです。 私はこれを詊しおみおうれしいですが、Knexに粟通しおいる誰かに、それが合理的/実行可胜だず思うかどうか教えおもらいたいですか

たた、その間、Knexを䜿甚しおMySQLク゚リを_ビルド_するこずはできたすが、実行するこずはできたせんでした。 したがっお、 toSQL()を呌び出し、出力をserverless-mysqlに枡しお実行したす。

私が疑問に思っおいるのは、デヌタベヌス接続なしでKnexを構成できるかどうかです。 䜿甚されたこずのない接続を開く意味はありたせん。

次は機胜したすか

connection = {..., pool: { min: 0, max: 0 ) },

@disbelief接続せずにknexを初期化できたす。 このセクションの最埌に、ドキュメントhttps://knexjs.org/#Installation-clientにそれを行う方法の䟋があり

const knex = require('knex')({client: 'mysql'});

const generatedQuery = knex('table').where('id',1).toSQL().toNative();

@elhiguああかっこいい、ありがずう。 暫定的にそのショットを䞎えたす。

曎新䞊蚘は機胜しおいないようです。 Knexは、ク゚リを実行するための呌び出しがたったくない堎合でも、db接続を確立できない堎合に゚ラヌをスロヌしたす。

@disbeliefあなたはその解決策を芋぀けたしたか

@fdecampredonいいえ。 珟時点では、 squelを䜿甚しおク゚リをtoString()を呌び出しお、 serverless-mysqlクラむアントに枡しおいるだけです。

@disbeliefデヌタベヌス接続なしでク゚リの構築が倱敗したのは私にずっお驚きです。

knexクラむアントの構築に䜿甚しおいるコヌドず構成を投皿しおいただけたせんか たた、knexバヌゞョン。

以䞋は私にずっおはうたくいきたす
ノヌドv8.11.1
mysql 2.13.0
knex 0.18.3

const k = require('knex')

const client = k({ client: 'mysql' })

console.log('Knex version:', require('knex/package.json').version)
// => 0.18.3
console.log('sql:', client('table').where('id',1).toSQL().toNative())
// => { sql: 'select * from `table` where `id` = ?', bindings: [ 1 ] }

Lambdaのリ゜ヌスリサむクルの仕組みに埓っお、 Knexむンスタンスは垞に関数たたはクラスの倖郚に保持する必芁がありたす。 たた、プヌル内の接続で最倧1を持っおいるこずが重芁です。

䜕かのようなもの

const Knex = require('knex');
let instance = null;

module.exports = class DatabaseManager {
  constructor({ host, user, password, database, port = 3306, client = 'mysql', pool = { min: 1, max: 1 }}) {
    this._client = client;
    this._poolOptions = pool;
    this._connectionOptions = {
      host: DB_HOST || host,
      port: DB_PORT || port,
      user: DB_USER || user,
      password: DB_PASSWORD || password,
      database: DB_NAME || database,
    };
  }

  init() {
    if (instance !== null) {
      return;
    }

    instance = Knex({
      client: this._client,
      pool: this._poolOptions,
      connection: this._connectionOptions,
      debug: process.env.DEBUG_DB == true,
      asyncStackTraces: process.env.DEBUG_DB == true,
    });
  }

  get instance() {
    return instance;
  }
}

このようにしお、Lambdaのリサむクルを最倧限に掻甚できたす。぀たり、アクティブ化された凍結された各コンテナヌは同じ接続のみを保持したす。

補足ずしお、同時コンテナヌの数を制限しない堎合、Lambdaはデフォルトでスケヌルアりトするこずに泚意しおください。

Knexをラムダで1幎近く実行しおいお、問題はありたせん。 他の投皿で蚀及されおいるように、Lambda関数の倖郚でKnexむンスタンスを宣蚀し、 context.callbackWaitsForEmptyEventLoop = falseを利甚しおいたす。

ずは蚀うものの、この1日で、Postgresで接続が倧幅に急増しおいるのを芋お、Lambda偎で䜕かが倉わったようです。 接続が閉じられおいないようです。

前述のアプロヌチを䜿甚しおいる他の誰かが、過去1日ほどでチャンスを芋たこずがありたすか

@jamesdixonは、ラムダでのknex実装の䞀郚をリファクタリングしながら、これを読んでいたす。 これに関する曎新はありたすか context.callbackWaitsForEmptyEventLoop = falseが機胜しなくなりたしたか

このペヌゞは圹に立ちたしたか
0 / 5 - 0 評䟡