10

node-postgresを使用して、postgresでnode.jsをいじり始めました。私がやろうとしたことの 1 つは、約 200,000 エントリのファイルを使用して、短い js を記述してデータベースにデータを入力することです。

しばらくすると (10 秒以内)、「エラー: 接続が終了しました」というメッセージが表示されるようになりました。これが node-postgres の使い方に問題があるのか​​、それとも postgres をスパムしていたからなのかはわかりません。

とにかく、この動作を示す簡単なコードを次に示します。

var pg = require('pg');
var connectionString = "postgres://xxxx:xxxx@localhost/xxxx";

pg.connect(connectionString, function(err,client,done){
  if(err) {
    return console.error('could not connect to postgres', err);
  }

  client.query("DROP TABLE IF EXISTS testDB");
  client.query("CREATE TABLE IF NOT EXISTS testDB (id int, first int, second int)");
  done();

  for (i = 0; i < 1000000; i++){
    client.query("INSERT INTO testDB VALUES (" + i.toString() + "," + (1000000-i).toString() + "," + (-i).toString() + ")",   function(err,result){
      if (err) {
         return console.error('Error inserting query', err);
      }
      done();
    });
  }
});

約 18,000 ~ 20,000 回のクエリの後で失敗します。これは client.query の使い方が間違っていますか? デフォルトのクライアント番号を変更してみましたが、うまくいきませんでした。

client.connect() も役に立たないようですが、それは私があまりにも多くのクライアントを持っていたためだったので、クライアントプーリングが最善の方法だと思います.

助けてくれてありがとう!

4

2 に答える 2

4

最大プールサイズに達していると思います。client.queryは非同期であるため、使用可能なすべての接続が返される前に使用されます。

デフォルトのプール サイズは 10 です。こちらを確認してください: https://github.com/brianc/node-postgres/blob/master/lib/defaults.js#L27

次のように設定して、デフォルトのプール サイズを増やすことができますpg.defaults.poolSize

pg.defaults.poolSize = 20;

更新: 接続を解放した後、別のクエリを実行します。

var pg = require('pg');
var connectionString = "postgres://xxxx:xxxx@localhost/xxxx";
var MAX_POOL_SIZE = 25;

pg.defaults.poolSize = MAX_POOL_SIZE;
pg.connect(connectionString, function(err,client,done){
  if(err) {
    return console.error('could not connect to postgres', err);
  }

  var release = function() {
    done();
    i++;
    if(i < 1000000)
      insertQ();
  };

  var insertQ = function() {
    client.query("INSERT INTO testDB VALUES (" + i.toString() + "," + (1000000-i).toString() + "," + (-i).toString() + ")",        function(err,result){
      if (err) {
         return console.error('Error inserting query', err);
      }
      release();
    });
  };

  client.query("DROP TABLE IF EXISTS testDB");
  client.query("CREATE TABLE IF NOT EXISTS testDB (id int, first int,    second int)");
  done();

  for (i = 0; i < MAX_POOL_SIZE; i++){
    insertQ();
  }
});

基本的な考え方は、比較的小さな接続プール サイズで多数のクエリをキューに入れているため、最大プール サイズに達しているということです。ここでは、既存の接続が解放された後にのみ、新しいクエリを作成します。

于 2015-03-17T14:00:49.073 に答える