すぐに忘れるので参照できるように雑にまとめ
Clients — Finagle 6.44.0 documentation とかを見るとすべて書いてあるので、基本的には公式を見たほうが良いです。 実装を読んだものも含んでいるのでfinagle 6.45以外で成り立つかは不明です。
種類について
以下の4種類がある。
- Buffering Pool
- Watermark Pool
- Caching Pool
- SingletonPool
Buffering Pool
finagle/BufferingPool.scala at finagle-6.45.0 · twitter/finagle · GitHub
bufferSizeを1以上にするとONになるがデフォルトはOFF。 Watermarkの方が小回りがきくので基本的には使わなくてよいはず・・?
Watermark Pool
finagle/WatermarkPool.scala at finagle-6.45.0 · twitter/finagle · GitHub
low(デフォルト0), high(デフォルト Int.MaxValue)、maxWaiters(デフォルト Int.MaxValue)の3つを設定して使う。
基本的にはlow ~ highの区間でコネクションを保持するもの。 最初のコネクションは0個なので常にこの区間にあるわけではなく、コネクションを作るときにlow個まではコネクションを保持し、それ以上は保持しないという動作。
high個以上のリクエストについてはそもそもコネクションを作らずwaitersキューに入れるという動作になっている。 このときlowを超えた分は基本的に随時connectしたりcloseしたりされるがwaiterが居る場合はcloseせずに使いまわす。 また、waitersキューに入れる際にキューサイズがmaxWaitersを超えていたらキューには追加せずTooManyWaitersExceptionが発生するようになっている。
Caching Pool
finagle/CachingPool.scala at finagle-6.45.0 · twitter/finagle · GitHub
WatermarkPoolだけだとlowを超えた瞬間に接続したり切断したりが繰り返されてしまう。
これを防ぐためにidleTime
に従って時間ベースでコネクションをキャッシュするのがCachingPool。
idleTimeというだけあって、コネクションが活用されている間はevictionされないようになっている。
ただし、idleTimeは目安であって実際には[ttl, ttl * 2)
のレンジでevictされる様子。
キャッシュされる個数はhigh - low個になっている。 デフォルトだとLong.MaxValueナノ秒キャッシュされるので、適宜調節しても良いかもしれない。
Singleton Pool
finagle/SingletonPool.scala at finagle-6.45.0 · twitter/finagle · GitHub
コネクションプールと言いつつ一つのコネクションのみを保持するプール ThriftMuxはコネクションを多重化しているのでプールいらないよねという事情により存在する。
使われ方
DefaultPoolを見ると、BufferPool/WatermarkPool/CachingPoolは組み合わせて利用するようになっている模様。 BufferPool(defaultオフ) => WatermarkPool => CachingPool のように順番にキャッシュ判定などがされるようになっている。(SingletonPoolは別枠)
どの条件で使われるかについては現状だと以下のようになっている。
プール名 | ONになる条件 | 備考 |
---|---|---|
BufferPool | bufferSize > 0 | defaultでは0で、基本的に変える必要はなさそう。 |
WatermarkPool | true | 常に有効になっている |
CachingPool | idleTime > 0.seconds && high > low | defaultだとLong.MaxValueナノ秒保持される |
役立つmetrics
Metrics — Finagle 6.44.0 documentation を見るのが良い。
pool_waiters
や pool_num_waited
を見ると待機キューが使われているかどうかなどを把握できる。
ちなみに pool_cached
はキャッシュされているコネクションの数を表すが、現在使われているコネクションはこの中には入らないようなのでサーバーに負荷がかかっている状態では0になったりするっぽい。(cachからgetするとdequeからpopされるためsizeが減る)