2

基本的に、この質問は次のようなものです: 同じ DB 接続を複数のプロセスで使用できますか (異なる map-reduce ジョブは実際には異なる独立したプロセスにあるため)。

これは少し些細な質問であることは知っていますが、誰かがこれにも答えることができれば素晴らしいことです: DB への接続の最大数 (DB をホストするサーバーで事前構成されている) が使い果たされ、新しいプロセスは新しい接続を取得しようとしますか? しばらく待ちますか。もしそうなら、この待機期間のタイムアウトを設定する方法はありますか。この特定のケースでは、PostGres DB に関して話しているのですが、DB との対話に使用される言語は Java です。

問題の状況を説明するために、複数の map-reduce ジョブ (約 40 個のレデューサー) を並行して実行しており、それぞれが PostGres DB を更新しようとしています。これらのプロセスからこれらの DB の読み取り/書き込みを効率的に管理するにはどうすればよいですか。注: DB は、map reduce ジョブが実行されている場所とは関係なく、別のマシンでホストされます。

接続プーリングは 1 つのオプションですが、特に 1 秒あたり数回の読み取り/書き込みの場合、非常に非効率になることがあります。

4

1 に答える 1

4

複数のプロセスで同じ DB 接続を使用できますか

いいえ、正気で信頼できる方法ではありません。ブローカ プロセスを使用することもできますが、接続プールを発明するまであと 1 歩です。

DB への接続の最大数 (DB をホストするサーバーで事前構成されている) が使い果たされ、新しいプロセスが新しい接続を取得しようとするとどうなりますか?

接続試行は SQLSTATE で失敗します53300 too_many_connections。待機すると、サーバーが他の制限を使い果たし、既存のクライアントへのサービスに問題が発生し始める可能性があります。


このような問題の場合、通常は C3P0 や DBCP などの JVM 内プーリングを行うツールを使用しますが、これは複数の JVM がある場合には機能しません。

必要なことは、PgBouncerPgPool-IIなどの外部接続プールを使用して、ワーカーからの一連の軽量接続を維持することです。プーラーは少数の実サーバー接続を持ち、それらをクライアントからの軽量接続間で共有します。

通常、接続プーリングは、アクティブな PostgreSQL ワーカー プロセスの数をハードウェアとワークロードに合わせて最適化し、作業のアドミッション コントロールを提供できるため、プーリングしないよりも効率的です。

別の方法は、1 つ以上のスレッド (スレッドごとに 1 つの接続) を持つライター プロセスを使用して、reduce ワーカーから完了した作業を受け取り、DB に書き込むことです。これにより、reduce ワーカーは次の作業単位に進むことができます。ライターが大幅に遅れた場合、reduce ワーカーに待機するように指示する方法が必要です。これに適した Java キューイング システムの実装がいくつかありますが、JMS を使用することもできます。

大量の小さなデータについては、IPC の提案を参照してください

以下を使用して、PostgreSQL への書き込み方法を可能な限り最適化することも価値があります。

  • 準備されたステートメント
  • commit_delay
  • synchronous_commit = 'off'サーバーがクラッシュした場合にいくつかのトランザクションを失う余裕がある場合
  • 作業をより大きなトランザクションにバッチ処理する
  • COPYINSERTまたはデータのブロックを挿入する多値の s
  • ひどい I/O を備えた Amazon EC2 インスタンスや 5400rpm ディスクを備えた RAID 5 ボックスではなく、便利なディスク サブシステムを備えたまともなハードウェア
  • fsync() のコストを削減するためのバッテリ バックアップ付きライトバック キャッシュを備えた適切な RAID コントローラ。大量の作業を実行できない場合やコミット遅延を使用できない場合に最も重要です。バッチ処理とグループコミットのために fsync レートが低い場合、影響は少なくなります。

見る:

于 2012-10-29T05:14:45.313 に答える