中年engineerの独り言 - crumbjp

LinuxとApacheの憂鬱

荒ぶるmongos様の解析

前回(荒ぶるmongos様)の続き

とりあえずgrepレベルでサラっと構造を読んでみた。

まだ追記します
一旦終わり!

解析途中経過

DBConnectionPool
コイツが重要っぽい
class DBConnectionPool : public PeriodicTask {
  :
}
PeriodicTask
このクラスは毎分起動taskDoWork()が叩かれる
PoolMap
DBConnectionPoolのメンバー。実際にコネクションを管理している。
typedef map<PoolKey,PoolForHost,poolKeyCompare> PoolMap;
PoolForHost
プール周りのロジックが詰まってる重要クラスっぽい。
PeriodicTask::Runner::run()
Periodic::taskDoWork():タスクに掛った時間がログに出力される

例>

Fri Aug  3 15:05:15 [PeriodicTask::Runner] task: DBConnectionPool-cleaner took: 102ms

ただし、、3ms以内だったモノはログ出力されない!!

という訳でクリーナは毎分動いてるっぽい。
クリーナーは働いてるのにコネクション数が増え続けるという事は、、、
ロジックの問題という事か・・・

追記1

と思ったら、簡単に見つかった!

bool PoolForHost::StoredConnection::ok( time_t now ) {
   // if connection has been idle for 30 minutes, kill it
   return ( now - when ) < 1800;
}

これ位configで設定できてもよくね?
とりあえず試してみよう。。

追記2

あっさり効いた!

そもそも必要無くなったコネクションを30分も抱えている事が問題だ。
取り敢えずコレは投入するとして、今回のケースでこれ以上積極的なロジックが必要か否かは要検討。。

追記3

Pull-requestしてみた。
https://github.com/mongodb/mongo/pull/278

さてさて、どうなるやら?