MySQLまたはMariaDBサーバーの前にロードバランサーまたはリバースプロキシを配置すると、データベースのセットアップが少し複雑になり、動作が異なる場合があります。理論的には、MySQLサーバーの前にあるロードバランサー(たとえば、Galeraクラスターの前にあるHAProxy)は、接続マネージャーのように機能し、何らかのバランシングアルゴリズムに従ってバックエンドサーバーに接続を分散する必要があります。一方、MySQLには、クライアント接続を管理する独自の方法があります。理想的には、予期しない動作を回避するためにこれら2つのコンポーネントを一緒に構成し、問題をデバッグするときにトラブルシューティングの表面を絞り込む必要があります。
このような設定をしている場合は、データベースサービスの全体的なパフォーマンスに影響を与える可能性があるため、これらのコンポーネントを理解することが重要です。このブログ投稿では、MySQLの max_connectionsについて詳しく説明します。 およびHAProxymaxconn それぞれオプション。タイムアウトは知っておくべきもう1つの重要なパラメータですが、これについては別の投稿で説明します。
MySQLの最大接続数
関連リソースHAProxyを使用したMySQL負荷分散-チュートリアルウェビナーリプレイとQ&A:ProxySQL、HAProxy、MaxScaleウェビナーリプレイとスライドをデプロイおよび管理する方法:MariaDBとHAProxyを使用してスケーラブルなデータベースインフラストラクチャを構築する方法MySQLサーバーに許可される接続の数は、 max_connectionsによって制御されます。 システム変数。デフォルト値は151(MySQL 5.7)です。
max_connectionsの適切な数を決定するには 、基本的な式は次のとおりです。
どこで、
**変数innodb_additional_mem_pool_size MySQL5.7.4以降では削除されています。古いバージョンで実行している場合は、この変数を考慮に入れてください。
そして、
上記の式を使用することで、適切な max_connections を計算できます。 この特定のMySQLサーバーの値。プロセスを開始するには、クライアントからのすべての接続を停止し、MySQLサーバーを再起動します。その特定の瞬間に実行されているプロセスの数が最小であることを確認してください。この目的には、「mysqladmin」または「SHOWPROCESSLIST」を使用できます。
$ mysqladmin -uroot -p processlist
+--------+------+-----------+------+---------+------+-------+------------------+----------+
| Id | User | Host | db | Command | Time | State | Info | Progress |
+--------+------+-----------+------+---------+------+-------+------------------+----------+
| 232172 | root | localhost | NULL | Query | 0 | NULL | show processlist | 0.000 |
+--------+------+-----------+------+---------+------+-------+------------------+----------+
1 row in set (0.00 sec)
上記の出力から、rootであるMySQLサーバーに接続しているユーザーは1人だけであることがわかります。次に、ホストの使用可能なRAM(MB単位)を取得します(「使用可能な」列の下を確認してください):
$ free -m
total used free shared buff/cache available
Mem: 3778 1427 508 148 1842 1928
Swap: 2047 4 2043
情報として、「使用可能」列には、スワップせずに新しいアプリケーションを起動するために使用できるメモリの見積もりが表示されます(カーネル3.14以降でのみ使用可能)。
次に、使用可能なメモリ、1928MBを次のステートメントで指定します。
mysql> SELECT ROUND((1928 - (ROUND((@@innodb_buffer_pool_size + @@innodb_log_buffer_size + @@query_cache_size + @@tmp_table_size + @@key_buffer_size) / 1024 / 1024))) / (ROUND(@@read_buffer_size + @@read_rnd_buffer_size + @@sort_buffer_size + @@thread_stack + @@join_buffer_size + @@binlog_cache_size) / 1024 / 1024)) AS 'Possible Max Connections';
+--------------------------+
| Possible Max Connections |
+--------------------------+
| 265 |
+--------------------------+
**変数innodb_additional_mem_pool_size MySQL5.7.4以降では削除されています。古いバージョンで実行している場合は、この変数を考慮に入れてください。
この例から、ホストが持っている使用可能なRAMに応じて、最大265のMySQL接続を同時に持つことができます。それよりも高い値を設定することは意味がありません。次に、MySQL構成ファイル内の[mysqld]ディレクティブの下に次の行を追加します。
max_connections = 265
MySQLサービスを再起動して、変更を適用します。同時接続の総数が265に達すると、mysqldサーバーに接続しようとしたときに「接続が多すぎます」というエラーが発生します。これは、使用可能なすべての接続が他のクライアントによって使用されていることを意味します。 MySQLは実際にmax_connectionsを許可します 接続するクライアントを+1します。追加の接続は、SUPER特権を持つアカウントで使用するために予約されています。したがって、このエラーが発生した場合は、rootユーザー(または他のSUPERユーザー)としてサーバーにアクセスし、プロセスリストを確認してトラブルシューティングを開始する必要があります。
HAProxyの最大接続数
HAProxyには、グローバル、デフォルト/リッスン、デフォルトサーバーの3種類の最大接続(maxconn)があります。 2つのリスナーで構成されたHAProxyインスタンスを想定します。1つはポート3307でリッスンするマルチライター用(接続はすべてのバックエンドMySQLサーバーに分散されます)、もう1つはポート3308でシングルライターです(接続は単一のMySQLサーバーに転送されます):
global
...
maxconn 2000 #[a]
...
defaults
...
maxconn 3 #[b]
...
listen mysql_3307
...
maxconn 8 #[c]
balance leastconn
default-server port 9200 maxqueue 10 weight 10 maxconn 4 #[d]
server db1 192.168.55.171 check
server db2 192.168.55.172 check
server db3 192.168.55.173 check
listen mysql_3308
...
default-server port 9200 maxqueue 10 weight 10 maxconn 5 #[e]
server db1 192.168.55.171 check
server db2 192.168.55.172 check backup #[f]
いくつかの構成行の意味を見てみましょう:
global.maxconn [a]
このHAProxyインスタンスへの接続が許可されている同時接続の総数。通常、この値はすべての中で最も高い値です。この場合、HAProxyは一度に最大2000の接続を受け入れ、それらをHAProxyプロセスまたはワーカーで定義されたすべてのリスナーまたはワーカーに配布します( nbproc を使用して複数のHAProxyプロセスを実行できます) オプション)。
この制限に達すると、HAProxyは接続の受け入れを停止します。 「ulimit-n」パラメーターは、この値に自動的に調整されます。ソケットはシステムの観点からファイルと同等であると見なされるため、デフォルトのファイル記述子の制限はかなり小さいです。おそらく、ファイル記述子のカーネルを調整して、デフォルトの制限を引き上げることができます。
defaults.maxconn [b]
すべてのリスナーのデフォルトの最大接続値。この値がglobal.maxconnよりも大きい場合は意味がありません 。
「listen」スタンザ( listen.maxconn )の下に「maxconn」行がない場合 )、リスナーはこの値に従います。この場合、mysql_3308リスナーは一度に最大3つの接続を取得します。安全のため、この値を global.maxconnと等しく設定してください 、リスナーの数で割った値。ただし、他のリスナーに優先順位を付けて接続を増やす場合は、 listen.maxconnを使用してください。 代わりに。
listen.maxconn [c]
対応するリスナーに許可される最大接続数。リスナーはdefaults.maxconnよりも優先されます 指定されている場合。この値がglobal.maxconnよりも大きい場合は意味がありません 。
マルチライターリスナー(mysql_3307)の場合のように、バックエンドサーバーへの接続を公平に分散するには、この値を listen.default-server.maxconnとして設定します。 バックエンドサーバーの数を掛けます。この例では、より適切な値は8ではなく12である必要があります[c]。この構成を使用することを選択した場合、db1とdb2はそれぞれ最大3つの接続を受け取ると予想されますが、db3は最大2つの接続を受け取ります(最小接続バランシングのため)。これは合計で8つの接続になります。 [d]で指定された制限に達しません。
一度に1つだけのバックエンドサーバーに接続を割り当てる必要があるシングルライターリスナー(mysql_3308)の場合、この値を listen.default-server.maxconn以上に設定します。 。
listen.default-server.maxconn [d] [e]
これは、すべてのバックエンドサーバーが一度に受信できる接続の最大数です。この値がlisten.maxconnよりも大きい場合は意味がありません またはdefaults.maxconn 。この値は、MySQLの max_connections以下である必要があります 変数。そうしないと、特にMySQLのタイムアウト変数がHAProxyのタイムアウトよりも低く設定されている場合に、バックエンドMySQLサーバーへの接続を使い果たすリスクがあります。
この例では、マルチライターGaleraノードに対して一度に最大4つの接続のみを取得するように各MySQLサーバーを設定しました[d]。シングルライターのGaleraノードは、[b]から適用される制限により、一度に最大3つの接続を取得します。他のノードに「バックアップ」[f]を指定したため、アクティブノードはこのリスナーに割り当てられた3つの接続すべてを一度に取得します。
上記の説明は、次の図で説明できます。
接続分布を要約すると、db1は最大6つの接続(3307から3 + 3308から3)を取得することが期待されます。 db2は3つの接続を取得し(db1がダウンした場合を除き、さらに3つ取得します)、クラスター内のトポロジーの変更に関係なく、db3は2つの接続を維持します。
ClusterControlを使用した接続の監視
ClusterControlを使用すると、UIからMySQLおよびHAProxy接続の使用状況を監視できます。次のスクリーンショットは、MySQL接続アドバイザ(ClusterControl-> Performance-> Advisors)の概要を示しており、クラスタ内のすべてのサーバーで現在およびこれまでに使用されたMySQL接続を監視します。
HAProxyの場合、ClusterControlはHAProxy統計ページと統合してメトリックを収集します。これらは[ノード]タブに表示されます:
上のスクリーンショットから、マルチライターリスナーの各バックエンドサーバーが最大8つの接続を取得していることがわかります。 4つの同時セッションが実行されています。これらは上部の赤い四角で強調表示されていますが、シングルライターリスナーは2つの接続を提供し、それぞれを1つのノードに転送しています。
結論
HAProxyとMySQLサーバーの最大接続数を構成することは、データベースサーバーへの負荷分散を確保し、MySQLサーバーの接続の過負荷や枯渇から保護するために重要です。