pgBouncerはうまく機能しますが、時々利用できなくなります


9

忙しいpostgres 9データベースの前でpgBouncerを実行しています。ほとんどの場合、問題なく動作します。しかし、数時間ごとに、psycopg2からの例外を除いて、アプリケーションからエラーメールが届きます。

OperationalError(「サーバーに接続できませんでした:要求されたアドレスを割り当てることができません。サーバーはホスト "neo-hulk"で実行されており、ポート6432でTCP / IP接続を受け入れていますか?」)

これは、タスクを実行しているセロリワーカーの束を備えたpythonアプリです。これらのエラーが発生したら、pgbouncer dbをチェックし、プールサイズが制限内であることを確認します。いくつかの実験を行った後、プールの最大サイズを400に、プールサイズを200に設定しました。プールモードは「セッション」です(リクエストはほとんど自動コミットで、ほとんどトランザクションはありません)。

何がpgBouncerをそのように「消失」させるのですか?それは短期間のみです(そして、全体としては、処理する要求の膨大な量と比較して、ごく少量の要求について話しています)が、失敗した要求は重要です。

ありがとう!


オペレーティングシステムとバージョン?Linuxの場合のカーネルバージョン?正確なPostgreSQLおよびPgBouncerバージョン?PgBouncerをデバッグログレベルで実行して、何か有用な情報が報告されていないか確認しましたか?
クレイグリンガー

Debian 6. Linuxバージョン2.6.32-5-amd64(Debian 2.6.32-48squeeze1)pgbouncerバージョン1.5.4 Postgres 9.1。ログは接続/切断をログに記録しません。これは少し多かったと思いましたが、これらのアプリエラーがスローされたときにエラーは発生していません。エラーはpsycopg2が原因で、対話するデータベースサーバーがないと考えていますが、この問題はpgbouncerより前には存在しませんでした
Harel

1
うーん、現在のPgBouncer、そしてカーネルは古くからありますが、かなり安定しています。PgBouncerでより詳細なロギングを有効にして-vvv、異常なログ出力を時間内のエラーと一致させることができるかどうかを確認する必要があると思います。
クレイグリンガー、

「set verbose = 1; reload;」を実行しました。pgbouncerシェルで、ログから異常なものを見つけることができませんでした。これは本番システムであるため、サービスを停止して-vvvを使用して非デーモンとして実行することはできませんでした。うまくいけば、同じ結果が得られます。このエラーは、pgbouncerにまったく接続できなかったこと、つまり、そのポートでリッスンしていないことを示していることに注意してください。常に何千もの接続があり、そのように少数が失敗するというのは奇妙です。
Harel

トリッキー; 潜在的な競合状態のように聞こえますが、何が/どこで...
クレイグリンガー

回答:


15

要求されたアドレスを割り当てることができませんエラーメッセージの」部分は、カーネルのTCPスタックから来ています。断続的に発生する場合、これは通常、待機状態のソケットが多すぎるために、使用可能なソケットのスペースが使い果たされていることを意味します(TIME_WAITまたはおそらくFIN_WAIT_1またはFIN_WAIT_2

ソケットポートの範囲はによって出力できますcat /proc/sys/net/ipv4/ip_local_port_range。通常のLinuxカーネルのデフォルト値は32768 61000です。

netstat -ton|grep WAITシステムがビジーの場合は、クライアントとpgBouncerのホストで結果を確認できます。この-oフラグは、待機状態に関連するタイムアウトカウンターを示します。

TCPソケットの総数が近い場合は61000-32768=28232、この範囲の枯渇が問題である可能性があります。閉じたソケットはTIME_WAIT通常の状態で60秒を費やすため、クライアントホストが1分間に28232回を超えて接続した場合、ポートが解放されるまで、新しい接続は前述のエラーで失敗します。

最初の回避策として、TCPポートの範囲を拡張できます。

 # echo "1025 65535" >/proc/sys/net/ipv4/ip_local_port_range

それは満足できないなら、チェックtcp_tw_recycleしてtcp_tw_reuseフラグを、またを通じて調整可能/proc/sys/net/ipv4sysctl

それらは(からman tcp)として定義されています:

       tcp_tw_recycle(ブール値;デフォルト:無効; Linux 2.4以降)
              TIME_WAITソケットの高速リサイクルを有効にします。これを有効にする
              作業時に問題が発生するため、このオプションはお勧めできません。
              NAT(ネットワークアドレス変換)を使用します。

       tcp_tw_reuse(ブール値;デフォルト:無効; Linux 2.4.19 / 2.6以降)
              TIME_WAITソケットの再利用を許可する
              プロトコルの観点から安全です。せずに変更しないでください
              技術専門家のアドバイス/リクエスト。

個人的にはtcp_tw_recycle、MySQLクライアントアプリでこの問題に直面したときに成功しましたが、これは推奨事項ではありません。TCPについての私の理解は、表面的なものでしかありません。


1
その答えは、TCPのバグの表面的な理解を示しています。有難うございます。ポートの範囲を拡大し、しばらく実行して、効果があるかどうかを確認しました。(設定後に再起動する必要がありますか?)
Harel

ポートの増加はそれを行っていると思います。これまでのところ、エラーは発生していません。netstat行の大まかなカウントは、クライアントで20Kに近いことを示しているため、そこから28Kのデフォルト制限までは長くありません。それをありがとう!
ハレル2014

1
良い!リブート後も保持さ/etc/sysctl.confれるnet.ipv4.ip_local_port_range = 1025 65535ように設定を配置したい。
DanielVérité2014

ありがとう。私はそれ以来エラーを受け取りましたが、それはそうではありません。それでもそれは良いことです。数日間実行すると、パーマが変更されます。他の変更が私を怖がらせているので、これまでのところうまくいくようでうれしいです:)
Harel
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.