MySQL道普請便り

第118回 MySQL Routerを使って負荷分散を検証する

この記事を読むのに必要な時間:およそ 2.5 分

MySQL関連のミドルウェアとしてMySQL Routerというものがあります。MySQL Routerは,アプリケーションとMySQLサーバー間をルーティングするための軽量なミドルウェアです。InnoDB Clusterのアプリケーションとの接続部分としても利用されており,負荷分散や高可用性の機能があります。

今回はMySQL Routerを使い,マスター1台,スレーブ2台のMySQLサーバーに対してスレーブ側にMySQL Routerを設定し,負荷分散としてラウンドロビンで設定してみましょう。

MySQL Routerのインストール

MySQL RouterはLinux,macOS,WindowsそれぞれのOSで動かすことが可能です。今回は筆者の環境であるCentOS 7に,yumコマンドを利用してMySQL Routerのバージョン8.0.19をインストールします。

$ wget https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm
$ sudo rpm -Uvh  mysql80-community-release-el7-3.noarch.rpm
$ sudo yum install mysql-router

これでインストール完了です。mysqlrouterコマンドを利用して,バージョンが表示できるか確認してみましょう。

$ mysqlrouter -V
MySQL Router  Ver 8.0.19 for Linux on x86_64 (MySQL Community - GPL)

MySQL Routerのバージョンが適切に表示されました。また,--helpまたは-? でヘルプを確認することができます。

もし,他の環境でインストールを行う場合やソースからコンパイルしてインストールをする場合は,公式ドキュメントのChapter 2 Installing MySQL Routerを参考にインストールしてください。

MySQL Routerの設定

yumコマンドを用いてインストールしたMySQL Routerは,/etc/mysqlrouter/mysqlrouter.confをデフォルトの設定ファイルとして読み込みます。コメントアウト以外の部分を表示してみると,下記のようにデフォルトでは設定されてあります。

$ grep -v '#' /etc/mysqlrouter/mysqlrouter.conf


[DEFAULT]
logging_folder = /var/log/mysqlrouter
runtime_folder = /var/run/mysqlrouter
config_folder = /etc/mysqlrouter

[logger]
level = INFO

[keepalive]
interval = 60

MySQL RouterはMySQLサーバーのmy.cnfの設定と同じように,[section name]のセクション名とoption名 = 値の形式で記述します。今回は,2台のMySQLのスレーブサーバー(127.0.0.1:3308, 127.0.0.1:3309)に対してラウンドロビンで接続をするように設定を追加してみます。

$ vim /etc/mysqlrouter/mysqlrouter.conf
~
~
## 下記設定を追加
[routing]
bind_address       = 127.0.0.1
bind_port          = 3318
destinations       = 127.0.0.1:3308, 127.0.0.1:3309
routing_strategy   = round-robin

今回設定したオプションは以下の通りです。

オプション名 説明
bind_address アプリケーションで接続するホスト情報を設定
bind_port アプリケーションで接続するポート情報を設定
destinations カンマ区切りでルーティングの宛先を設定
routing_strategy MySQL Routerがどのようにルーティングするかを設定

より詳細な設定については,公式ドキュメントの4.3.2 Configuration File Optionsを参考にしてください。

MySQL Roouterの動作確認

それでは設定したMySQL Routerを起動して,ラウンドロビンで接続できるか確認してみましょう。今回,MySQL Routerはsystemdを用いて起動します。

# systemctl start mysqlrouter
# systemctl status mysqlrouter
● mysqlrouter.service - MySQL Router
   Loaded: loaded (/usr/lib/systemd/system/mysqlrouter.service; disabled; vendor preset: disabled)
   Active: active (running) since Thu 2020-03-19 02:25:56 JST; 13s ago
 Main PID: 22387 (main)
   CGroup: /system.slice/mysqlrouter.service
           └─22387 /usr/bin/mysqlrouter -c /etc/mysqlrouter/mysqlrouter.conf

起動が確認できました。

実際にログファイル/var/log/mysqlrouter/mysqlrouter.logを確認してみましょう。

# tail -f /var/log/mysqlrouter/mysqlrouter.log
2020-03-19 02:25:56 keepalive INFO [7f3728c9f700] keepalive started with interval 60
2020-03-19 02:25:56 keepalive INFO [7f3728c9f700] keepalive
2020-03-19 02:25:56 routing INFO [7f3723fff700] [routing] started: listening on 127.0.0.1:3318, routing strategy = round-robin
2020-03-19 02:26:56 keepalive INFO [7f3728c9f700] keepalive

127.0.0.1:3318でLISTENするようになりました。

ssコマンドで確認してみると,実際にポート3318がLISTEN状態であることが確認できます。

$ ss -natu | grep 3318
tcp    LISTEN     0      128    127.0.0.1:3318                  *:*

mysqlクライアントを利用して127.0.0.1:3318に接続し,各スレーブにつながるか確認します。

$ mysql -u root -h 127.0.0.1 -P 3318 -p
mysql> SELECT @@port;
+--------+
| @@port |
+--------+
|   3308 |
+--------+
1 row in set (0.00 sec)

ポート3308のMySQLサーバーに接続されました。もう一度127.0.0.1:3318に接続してみます。

$ mysql -u root -h 127.0.0.1 -P 3318 -p
mysql> SELECT @@port;
+--------+
| @@port |
+--------+
|   3309 |
+--------+
1 row in set (0.02 sec)

今度はポート3309のMySQLサーバーに接続しました。実際に何度か接続を繰り返すと,スレーブのサーバーを交互にに接続することが確認できます。ラウンドロビンとして設定ができているようです。

続いて,ポート3309のMySQLサーバーが故障した場合どうなるかを検証してみましょう。ポート3309のMySQLサーバーをkillコマンドでMySQLのプロセスを落とし,mysqlクライアントで再度127.0.0.1:3318に何度か接続してポートを確認してみます。

mysql> SELECT @@port;
+--------+
| @@port |
+--------+
|   3308 |
+--------+
1 row in set (0.00 sec)

何度接続しても,ポート3308のMySQLにのみに接続されるようになりました。再びポート3309のMySQLサーバーを起動して接続すると,再度交互に接続します。

このように,MySQL Routerを用いることで負荷分散が容易にできたり,接続できなくなったMySQLに向かないようルーティングされるようになることが確認できました。

まとめ

今回はMySQL Routerを用いてスレーブの負荷分散として,ラウンドロビンで接続できるように設定してみました。アプリケーションの設定する際にread_onlyなスレーブが複数台ある場合は,MySQL Rourterで負荷分散の管理を任せることを検討しても良いかもしれません。

著者プロフィール

深町日出海(ふかまちひでみ)

GMOメディア株式会社のデータベースエンジニア。主にOracleとMySQLを担当。得意なプログラム言語はJava。MySQLの好きなところはTABLEやINDEXの識別子に64byteまで使えるところ。

Twitter:@lhfukamachi