質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.31%
Heroku

HerokuはHeroku社が開発と運営を行っているPaaSの名称です。RubyやNode.js、Python、そしてJVMベース(Java、Scala、Clojureなど)の複数のプログラミング言語をサポートしている。

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

Q&A

解決済

1回答

1724閲覧

Webアプリのデータベース接続におけるコネクションプールの考え方について

mi_ho

総合スコア34

Heroku

HerokuはHeroku社が開発と運営を行っているPaaSの名称です。RubyやNode.js、Python、そしてJVMベース(Java、Scala、Clojureなど)の複数のプログラミング言語をサポートしている。

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

0グッド

0クリップ

投稿2023/08/23 01:52

編集2023/08/23 04:59

現状・ここまでで分かったこと

heroku + Node.jsでWebアプリを作っています。
データベースには、herokuのMySQLアドオンJawsDBの無料プランkitefin sharedを利用中です。
kitefin sharedプランには”Connections”が10までという制限があり、この”Connections”が何に当たるかわからずこちらの質問をしたところ、

Web アプリから DB への接続は、ブラウザからのリクエストのたびに接続するのではなく、あらかじめいくつか接続しておいて、それを使い回す手法がよく使われますが、その接続の上限ってことでしょう。
https://workteria.forward-soft.co.jp/blog/detail/10210

とコメントいただき、一度確立したDB接続を維持して使い回すコネクションプーリングという手法を教えていただきました。
Node.jsでコネクションプールを作るmysql.createPoolには、connectionLimitという同時接続できる上限を示すパラメータがあり、これはデフォルトでは10になっているようです。
JawsDBの”Connections”は恐らくこれに当たるものかと思われます。

私はコネクションプールという概念をそもそも知らず、Webアプリで毎回DB接続→切断を繰り返す設計をしていました。
具体的には、DB接続が必要な時に、毎回サーバサイド(Node.js)で、mysql.createConnectionconnection.connectconnection.queryconnection.endをしていました。
調べたところ、この方法は良い方法ではなく、WebアプリではDBのコネクションをコネクションプールに貯めこんで使いまわす方法が定石のようです。

理由の説明は省きますが、WebアプリがDBと接続するときには、DBのコネクションをコネクションプールに貯めこんで、使いまわすのが定石なのです。

質問

やっていることで考えると、コネクションプールにコネクションを10個作っておいて空いているやつを使っていくのと、必要なときに毎回DB接続→切断を繰り返すのでは、前者の方がが処理負荷が抑えられるのは想像できますが、瞬間的な”Connections”の数については、どのような違いが出るのかまだわかりません。
呼び出し方が違うとはいえ、結局どちらも、その瞬間に使われている"Connections"数は同じなのでは?という気がします。

「"Connections”数的には両者そんなに変わらないが、コネクションプールを使う手法であれば、connectionLimitを設定できるから、JawsDBの”Connections”上限をより確実に回避できるので、コネクションプールを使うべき」、という考え方で合っていますでしょうか?

調べてわかったことを追記していきます

こちらの質問をみると、app.get内にデータベースへの接続&切断を書くことで、
サーバ起動時createConnection→1接続だけ作られる
サーバ終了時→停止
とできるようです。
app.get内で作られた1接続を使い回すのに、コネクションプールが必要、ということ?

ーーー
こちらの記事にて
コネクションプールを作ったとしても、デフォルトではコネクションは10秒しか維持されずにdisconnectionされるらしい。

(コネクションプールをしても)デフォルトで10秒後に切断されるそうです。
ということは10秒に1回アクセスのあるアプリでそのままプールを使っても、何の意味がないことになります。
idleTimeoutMillis: 600000 // 自動切断時間(ミリ秒)
これで1分はコネクションが保持されることになります。
また、この値を0にすれば、自動切断自体を無効化することができます。

10秒に何回もアクセスがあるようなアプリであれば、その10秒間では1つの接続を使いまわせるということ?

ーーー
こちらの記事にて(Deepl)

connection.end()は、MySQLへのクエリ送信を停止するとき、つまりアプリケーションが停止するときにのみ呼び出されます。すべてのクエリに同じコネクションを使用する(またはコネクションプールを使用してより効率的にする)。

app.get内にデータベースへの接続&切断を書いてサーバ起動時のみ1回接続を作り、それを使い回す(コネクションプールを使えばより効率的?)
しかし、毎回クエリ実行の度にconnection.endしている人もいる…

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

こちらの質問のコメント・自己回答を踏まえての私の理解をまとめておきます。

コネクションプールの主目的は、接続を使い回すことによる接続負荷の軽減ですが、その副産物として、接続数の管理ができるという点が、接続数制限のある場面では大きくメリットと言えるようです。

毎回DB接続→切断をする手法でも、毎回切断(connection.end)するなら無限に増えていくことは無いし、処理中に使用される接続数はコネクションプーリングと変わらないのでは?というのが私の疑問でしたが、
処理のタイミング(connection.endする前)が被ってしまうと接続数が増えてしまう、つまり単純に考えれば10人以上のユーザがせーのでDB接続のいる処理をした場合、瞬間的に接続数10になってしまうということかなと思います(おそらく)。
そう考えると、やはり毎回DB接続→切断をする手法は、DB接続数に制限がある環境などでは危ういかなと思います。

コネクションプール使用の場合でも、処理のタイミングが被ればDB接続数は増えていくことに変わりはないですが、コネクションプールを使用すれば最大接続数を設定でき、それを越す場合は利用可能な接続が空くまで待ってくれるという意味で、接続数のマネジメントができる点で重宝されているようです(おそらく)。
Node.jsでコネクションプールを作るcreatePoolには、同時接続できる上限を表すオプションconnectionLimit(デフォルト10)を設定でき、これを超えた場合は接続が1つ解放されるまで待機するようによしなに管理してくれるようです。その際エラーは出ず、ユーザは少し遅延を感じる程度とのことです。
参考:
https://github.com/mysqljs/mysql#pooling-connections
https://stackoverflow.com/questions/45522907/how-does-connectionlimit-work-in-node-mysql
試しに、connectionLimit: 1にして、releaseせずに何回もpool.getConnectionしてみましたが、ちゃんと1回実行後にずっと待機してくれたので、設定した connectionLimitの数に合わせてマネジメントしてくれるようです。
connectionLimitを設定しておけば、瞬間的に処理が多く重なってしまっても、設定している値は絶対に超えないように管理してくれるので安心、と理解しました。
自分の作っているものもコネクションプール使用に切り替えました。

投稿2023/08/25 04:30

編集2023/08/25 04:45
mi_ho

総合スコア34

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.31%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問