mita2 database life

主にMySQLに関するメモです

MySQL Connection Pooling と Persistent Connections はチョット違うという話

コネクションプーリングのメリット

コネクションプーリングは、一度確率したコネクションを使い回す仕組みです。TCP 3-way ハンドシェイクやDBの新規接続処理をスキップすることで、パフォーマンスを向上させる効果があります。

ただ、私の経験ではコネクションプーリングは「しても、しなくてもどっちでも良い」ケースがほとんどでした。接続処理以外の部分が占める時間やリソースの方が圧倒的に多いケースがほとんどではないでしょうか。

一部、アプリケーションサーバとDBサーバの距離が非常に長く、RTT(往復時間)が大きい場合に効果があった経験はあります*1

Connection Pooling と Persistent Connections

コネクションプーリングと似た仕組みとして、持続的データベース接続 (Persistent Connections) があります。 コネクションプーリングと持続的データベース接続は厳密に言うと少し違うものなのですが、どちらも接続を使い回す仕組みなので、私は両方「プーリング」と呼んでしまうことが多いです。その方が、通じやすいので。。。

コネクションプーリング (Connection Pooling)

アプリケーションはコネクションプールからコネクションを取出し、使い終わったら、プールにコネクションを戻します。 DBへアクセスするタイミングでのみコネクションを利用するため、アプリケーションのスレッド数(HTTPのWokerスレッド)より少ないコネクション数で済みます。HTTP の Worker スレッド 数とプールされるコネクション数は別々に管理されます。プールする接続数はドライバの設定で管理します。

f:id:mita2db:20200802161506p:plain
connection pooling

プールから払い出せるコネクションがなくなると、コネクションが返却されるのを待つか、エラーになります。

「コネクションプーリング」というとこのタイプの仕組みをイメージされる方が多いのではないでしょうか。Nodejs の mysql2 はこのタイプです。

持続的データベース接続 (Persistent Connections)

Apache (Prefork) + PHP はこのタイプです。WebサーバのWokerスレッド(プロセス)とDBのコネクションが1:1で対応します。 プールが存在しないため、WebサーバのWokerスレッド数と同じ数のコネクションが張られます。

f:id:mita2db:20200712151937p:plain
persistent connection

基本的にWebサーバのWokerスレッドが存在し続ける限り、コネクションが残り続けます*2。WebサーバのWokerスレッド数を増やすと連動して、DBへのコネクション数も増えます。そのため、コネクションプーリングとは異なり、HTTPサーバのWokerスレッド数を増やす場合は、接続上限に達しないよう MySQLmax_connectionsの値も増やしておく必要があります。コネクションプーリングと比較して、コネクション数のコントロールが難しい仕組みです。

*1:あと、TLSを使っている場合も効果ありそう

*2:MySQLのwait_timeoutに達して、DB側がコネクションを切るケースはあります