目次
Rubyを使った効率的なスクリプトの書き方を紹介
コネクションプール
データベースにアクセスするときに必要なコネクションを確立するためにはある程度の時間がかかります。そこで、一度確立したコネクションは解放せずに一定数プールしておいて次回のアクセス時に使い回すことを考えます。このコネクションプールという仕組みをクライアント側で実装することで、コネクションをプールしておくためのメモリなどは別途必要にはなりますが、アクセスのためのコネクション確立処理が不要になるため、確立処理に時間がかかる場合には全体として処理が高速化されます。
Rails の config/database.yml には pool という設定値があります。これによって、データベースのクライアントである Rails のコネクションプールの最大値を設定できます。例えば pool を 5 に設定するとデータベースにアクセスが必要なリクエストを並列して最大で 5 つ同時に処理できます。ただし 5 を越えるリクエストがなされると、越えた分のリクエストは 5 つのコネクションを利用したリクエスト処理が完了するまで待たされることになります。そして、config/database.yml の設定値 timeout ミリセカンド経過してもコネクションが得られないリクエストはタイムアウトエラーになります。データベースへのアクセスが必要なリクエストを大量に同時処理しなければならない Rails アプリケーションの場合は pool または timeout の値を上げることで対応します。
確立されたコネクションは MySQL の場合、SHOW PROCESSLIST によってスレッドとして確認できます。サーバ側ではコネクションが増加するとメモリなどのリソースが消費されるため、/etc/my.cnf などで max_connections によって上限を設定します。現在の設定値は以下のコマンドで確認できます。
mysql> SHOW GLOBAL VARIABLES LIKE 'max_connections';
+-----------------+-------+
| Variable_name | Value |
+-----------------+-------+
| max_connections | 151 |
+-----------------+-------+
1 row in set (0.00 sec)
そのうち、実際に現在使用されているコネクション数などは以下のコマンドで確認します。自分以外は誰も接続していないようです。
mysql> SHOW GLOBAL STATUS LIKE 'threads_%';
+-------------------+-------+
| Variable_name | Value |
+-------------------+-------+
| Threads_cached | 7 | ←使い回すためにMySQL側でキャッシュされているスレッド (クライアント側の pool と区別)
| Threads_connected | 1 | ←現在の接続されているスレッド数
| Threads_created | 809 | ←新しいスレッドが作成される度に増加 (cached 値が小さいと作っては壊すためすぐ増加)
| Threads_running | 1 | ←スリープ状態でないスレッド数
+-------------------+-------+
4 rows in set (0.00 sec)
スレッドのキャッシュ数の上限値設定は以下のコマンドで確認できます。
mysql> SHOW GLOBAL VARIABLES LIKE 'thread_cache_size';
+-------------------+-------+
| Variable_name | Value |
+-------------------+-------+
| thread_cache_size | 9 |
+-------------------+-------+
1 row in set (0.00 sec)
各コネクションのステータスなどの情報を詳細に確認したい場合は更に以下のコマンドを実行します。Info に "show processlist" とあります。確かに自分のプロセスのようです。
mysql> SHOW PROCESSLIST;
+-------+------+-----------+------+---------+------+-------+------------------+
| Id | User | Host | db | Command | Time | State | Info |
+-------+------+-----------+------+---------+------+-------+------------------+
| 81276 | root | localhost | NULL | Query | 0 | init | show processlist |
+-------+------+-----------+------+---------+------+-------+------------------+
1 row in set (0.00 sec)
ちなみに、過去の最大同時接続数は以下のようにして確認します。
mysql> SHOW GLOBAL STATUS LIKE 'max_used_connections';
+----------------------+-------+
| Variable_name | Value |
+----------------------+-------+
| Max_used_connections | 8 |
+----------------------+-------+
1 row in set (0.00 sec)
あまり参考にならない情報かもしれませんが、累計で作成されたコネクション数は以下のように確認できます。作成された累計スレッド数 Threads_created
と区別してください。
mysql> SHOW GLOBAL STATUS LIKE 'connections';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Connections | 81335 |
+---------------+-------+
1 row in set (0.00 sec)
バッファプール
InnoDB にはバッファプールという概念があります。名称は似ていますが、クライアント側の仕組みであるコネクションプールとは無関係です。現在の設定値は以下のコマンドで確認できます。
mysql> SHOW GLOBAL VARIABLES LIKE 'innodb_buffer_pool_size';
+-------------------------+-----------+
| Variable_name | Value |
+-------------------------+-----------+
| innodb_buffer_pool_size | 134217728 |
+-------------------------+-----------+
1 row in set (0.00 sec)
134217728 バイト (128 MB) であることが分かりました。これだけのメモリ領域が InnoDB のキャッシュとして利用できるということになります。サイズが大きければ大きいほど、ディスクアクセスの回数を低減させることができるため、処理が高速になります。ただし、あくまでもキャッシュですので不足していることによって事故が発生することはありません。
記事の執筆者にステッカーを贈る
有益な情報に対するお礼として、またはコメント欄における質問への返答に対するお礼として、 記事の読者は、執筆者に有料のステッカーを贈ることができます。
さらに詳しく →Feedbacks
ログインするとコメントを投稿できます。
関連記事
- MySQL レプリケーション設定 (2段, 3段)MySQL DB サーバは自身へのクエリをバイナリログとして書き出すことができます。レプリケーションとは、追加の MySQL DB サーバが、別の MySQL DB サーバが出力したバイナリログを自分のリレーログとよばれるログにコピーして、更にリレーログに記載されたクエリを自分自身のテーブルに実行する機能です。バイナリログを出力する DB をマスターとよび、自分のリレーログにコピーする DB をス...
- MySQL 5.7 インストール手順2016/11/07 時点、多くの環境では yum レポジトリ等に mysql 5.7 が含まれていません。公式ページからダウンロードしてインストールする手順を二つまとめます。 yum レポジトリを追加する手順 [Installing MySQL on Linux Using the MySQL Yum Repository (mysql 5.7)](http://dev.mysql.com/do...
- MyBatis 3 サンプルコード (Java/MySQL/Gradle)MyBatis は、JDBC を直接利用せずに、XML ファイル等で用意した SQL 文を利用して DB にアクセスするための Java ライブラリです。内部的には JDBC が利用されているため、JDBC のインストールは必要です。同様のライブラリに Hibernate ORM があります。DB は特に MySQL を対象として、MyBatis バージョン 3 の
- MySQL HandlerSocket Plugin の簡単な使用方法HandlerSocket は MySQL プロセス内のスレッドとして動作する、MySQL の NoSQL フロントエンドです。独自のプロトコルを用いて TCP 通信を行います。SQL 構文の解析が不要、プロトコルがシンプルなどの理由によって、単純な DB アクセスが高速に実行可能になります。MariaDB であれば[標準プラグインとして付属](https://mariadb.co
- Spring Boot から MyBatis を利用するための設定 (Gradle/MySQL)MyBatis を Spring Boot で利用するための基本的な設定およびサンプルコードをまとめます。サンプルコードにおいては、特に MySQL を対象とします。 MyBatis Spring-Boot-Starter チュートリアル