pg_pconnectに気をつけろ!!

37歳になりました.いい年こいて相変わらずいきます.

PHPであればpg_pconnect、Java+TomcatであればTomcatのコネクションプール機構をそのまま、その他アプリケーションフレームワークのレベルで提供されるコネクションプール機構があるようならそれを、必ず使うべきだ。

pg_pconnect()ってこれね.

経験上pg_pconnect()を使うと本気であまり接続が切れません.切れる条件としては多分この辺.

  1. httpdがMaxRequestsPerChildなりSEGFAULTの都合で死んだ
  2. PostgreSQL側の設定でtimeoutした
  3. initscriptなりで停止や再起動させた

その上でhttpdって何をするかというと,いわゆるHTMLやXML(フィードなど)の生成処理をするだけじゃなく,画像の処理もするんですね.CSSのファイルを読み込んだりJavaScriptのファイルを読み込んだりもしますね.
一度PHPでリクエストを受けたプロセスはそれらにもPostgreSQLとのセッションは張られっぱなしです.

つまり100リクエスト受けられるようにすると本当に100本セッションが張られる場合があります.HTML(PHPの処理)をほぼ同時に100本リクエストされたわけでなくとも.
こういう状態たちが悪いんです.アクセスログを見ても大してHTMLとかリクエストを受けていないのにnetstatなりpsなりで状態を見るとやたらセッションがたくさんあるんですよね.

視点を変えてもしウェブサービスでインフラの設計をするなら…という場合の狭いスコープでの質問です.

  1. httpdは最大どれ位同時のリクエストを受けられるように設計しますか?
  2. PostgreSQLは最大どれ位同時のリクエストを受けられるように設計しますか?

上記にどれ位差異がありますか? ふつー商用を名乗ったり1サーバーで複数コンテンツ,複数媒体とか遣り出したら最低100位は設定しますよね.
ついでにバッチ処理とかもしますよね.キャッシュ生成だったり統計テーブル更新だったりなんやかんやもありますね.
PostgreSQL側もメモリー使用量のチューニングなどなどしていかないといけないのに,マージン込みじゃなく常に3桁レベルの接続を意識しなければなりません.

結論

おこちゃまなので結論が先にないわけですが,やっと結論.

あなたはそれでもpg_pconnect()を使いますか? それとも障害対応で人間辞めますか?
そんなにpg_pconnect()したいなら(常にお勧めできるわけじゃないけど)pgpoolを検討した方がいいと思うよ.ってことで.

あわせて読みたい:

ってあちらにもリンクがあった(笑

余談

チューニングはえてして最初は徹底的にやりづらい.しかし気をつけるべきは「過負荷になってからチューニングで対処」はやけどのモト.
黒ひげ危機一髪的に障害を起こす可能性がより高い状態ということを認識しよう.
そんな状態ならもしあまりノウハウがない人がconfigureしたりソース読んだりしながらDBのチューニングに1人月まるまるかけるならハードウェアリプレースした方がいいかもね.
2人月かけたら正社員ならきっと100万位のコストになるよ(社員コストって給料だけじゃないですよね).
2人月分を1人月分資材調達,1人月分構築,交換に使う方がぐっと効果がでるかもしれないですね.チューニングノウハウがそもそもないなら構築にそもそも1ヶ月もいらないので資材にまわしましょう.

もうCentOS入れて運用中のPostgreSQLのバージョンと同じバージョンのrpmを拾ってきてインストールして今のPGDATAを/var/lib/pgsql/data/にでもコピーしてENDでいいじゃない.
そんな程度の作業なら構築限定だと5営業日あればそこそこのスキルでも十分できますよ(資材調達期間もあるし停止計画を作ってると実際もう少し「期間」は必要だと思いますけど.実働としてね).

たとえばそれであまった資産で改めてじっくりチューニングとか取り込めるかもしれないしね.検証環境を作ったり別様とに流用できちゃうかもしれない.

もしくはメモリーを載せられるだけ載せたりHDDをもっと早いものに交換したり,外部にHDDが6本位つめる箱用意してRAID 0+1(パフォーマンス出るならRAID 5とかでもOK)とかで構成してeSATA経由接続にしたり(さすがにFCとか言わない).postgresql.confの調整はざっくりと程度で.

余談その2

23:04 (xxxxxx) 個人的には、pgbouncerをお勧めしますよ

と天の声が.誰かレビューきぼん.

関連記事: