Oracle社より、MySQL Routerが発表されました。
Community版でも使えるし、早速試してみようじゃないの。
まず、MySQL Routerがどんなものなのか、から。
(ドキュメントはこちら)
MySQL Routerは、アプリケーションからのアクセスを透過的にMySQL Serverに振り分けるためのソフトウェアです。
アプリケーションからのアクセス先は固定のまま、
実際のアクセスはMySQL Routerが振り分けることで負荷分散を実現できます。
アーキテクチャの図はマニュアルにあるので、こちらを参照してください。
MySQL Routerのルーティング機能、MySQL Fabric Cache機能は共にプラグインとして実装されていることは
押さえておくべきでしょう。
ほか、アプリケーションからのクエリは全て、
MySQL Routerの基本機能であるConnection Routing Pluginを介してMySQL Serverに接続されますが、
この時、MySQL Routerはクエリの中身を見ないので、
MySQL Routerを使うことによるオーバーヘッドはさほどないはずです。
ところで、このMySQL Routerは、MySQL Fabricと関わりがある製品で、
MySQL Fabricは対応するコネクターが存在するプログラム言語(Java、PHP、Python)でしか利用できない、
という点をカバーするために生まれたそうです。
このため当然、MySQL RouterにはMySQL Fabric Pluginが存在します。
ただし、MySQL Fabric Pluginでどこまでのことができるのか、
についてはまだ情報が少なすぎるので、
それをこれから確かめてみよう、というわけ。
それでは、もう少し細かい使い方について見ていきましょう。
インストールパッケージについては、RHEL7であればRPMパッケージが公開されています。
RHEL6以前はRPMパッケージがないため、ソースから自前でビルドするしかない。
しかも、RHEL6のデフォルトCライブラリではバージョンが古くてビルドできないのでアップデートしなきゃいけない。
今回の検証では、とりあえずMySQL Router動かすまでは簡単な方がいいですし、
多少RHEL7入れるのは面倒ですが(実際入れるのはCent)、
後の憂いを絶つためにも、ここはがんばってCentOS 7をインストールしたVMを作成しました。
そして、MySQL Routerはどのサーバにインストールすべきか、ですが、
これはAPサーバに同居させるのが良いでしょう、
とマニュアルにあります(Recommendation参照)。
では早速インストールしてみましょう。
マニュアル的にはyumレポジトリを使うのが推奨らしいですが、
環境によってはyumが使えないことも多々あるかと思うのでrpmコマンドで。
[root@cent7-mysql57-1 ~]# rpm -ivh mysql-router-2.0.2-1.el7.x86_64.rpm 準備しています... ################################# [100%] 更新中 / インストール中... 1:mysql-router-2.0.2-1.el7 ################################# [100%]
簡単ですね。
ちなみに、この環境はすでにMySQL Serverが入っている環境なので、
MySQLのライブラリ等に依存している可能性は否定できません。
もしMySQL Routerのみをインストールすることを検討されている方は、
その点ご注意ください。
ではルーティングの設定に入ります。
MySQL Routerでは、MySQL Server同様、コンフィグファイルが存在します。
デフォルトでは/etc/mysqlrouter/mysqlrouter.iniがそれです。
ここにおかれているファイルは自動で読み込まれるので、
このファイルをいじるのが定石っぽいですね。
まずはMySQL Fabricは関係ない、通常のルーティング設定から。
いきなりですが、設定したmysqlrouter.iniはこんな感じです。
[root@cent7-mysql57-1 ~]# cat /etc/mysqlrouter/mysqlrouter.ini # Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; version 2 of the License. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # # MySQL Router configuration file # # Documentation is available at # http://dev.mysql.com/doc/mysql-router/en/ [DEFAULT] logging_folder = /var/log/mysqlrouter/ plugin_folder = /usr/lib64/mysqlrouter runtime_folder = /var/run/mysqlrouter config_folder = /etc/mysqlrouter [logger] level = info # If no plugin is configured which starts a service, keepalive # will make sure MySQL Router will not immediately exit. It is # safe to remove once Router is configured. [keepalive] interval = 60 # Added by UCO [routing:ReadWriteServers] bind_address = 127.0.0.1:7001 destinations = 192.168.2.222:3306,192.168.2.222:3308,192.168.2.222:3310 mode = read-write [routing:ReadOnlyServers] bind_address = 127.0.0.1:7002 destinations = 192.168.2.222:3307,192.168.2.222:3309,192.168.2.222:3311 mode = read-only
default、logger、keepaliveの設定については特段いじる必要性を感じなかったので、
そのままにしました。
その下、routingセクションが肝心なところで、
ここでルーティングルールを決めます。
といっても書くことは極めてシンプルで、
bind_addressでどのアドレスに対するアクセスをルーティングするか、
destinationsでルーティング先のMySQL Server、
modeでRead WriteかRead Onlyかを決めます。
なお、destinationsでの指定は、RWモードでは先頭のアドレスにのみクエリが集中し、
ROモードではラウンドロビンでの読み取りになるそうです。
今回の例では、192.168.2.222のサーバにMySQLを乗せており、
3306、3308、3310ポートのものがRWモード、
3307、3309、3311ポートのものがROモードで動いている設定になります。
アプリからの接続の際、127.0.0.1の7001番ポートを指せばRW、
7002番ポートを指せばROサーバに接続することになります。
ちなみに、ここからは読み取れないですが、
RWモードのMySQL ServerはROモードのMySQL Serverのマスターになっています。
実構成ではおそらくこのように、MasterにRW、SlaveにROモードを設定する形が多いと思われます。
では、早速動かしてみましょう。
[root@cent7-mysql57-1 ~]# mysqlrouter & [1] 4941 [root@cent7-mysql57-1 ~]# Logging to /var/log/mysqlrouter/mysqlrouter.log [root@cent7-mysql57-1 ~]#
下記JAVAプログラムを実行。
import java.sql.*; class routertest{ public static void main(String[] args){ try{ String driver = "com.mysql.jdbc.Driver"; String url = "jdbc:mysql://127.0.0.1:7001"; String user = "ap_user"; String password = "ap_user"; Class.forName (driver); Connection con = DriverManager.getConnection(url, user, password); Statement stmt = con.createStatement (); String sql= "insert into test.t1 values(null, 'insert from app server')"; int num = stmt.executeUpdate(sql); stmt.close(); con.close(); } catch (SQLException e){ System.err.println("SQL failed..."); e.printStackTrace (); } catch (ClassNotFoundException ex) { ex.printStackTrace (); } } }
実行コマンド
[root@cent7-mysql57-1 ~]# javac routertest.java [root@cent7-mysql57-1 ~]# java routertest
さて、予想結果としては、
3306番ポートのMySQLに更新が行っているはずですが、、、?
3306番MySQLにて
mysql-3306> select * from test.t1; +------+------------------------+ | col1 | col2 | +------+------------------------+ | 1 | insert from app server | +------+------------------------+ 1 row in set (0.01 sec)
予想通りですね。
ちなみに、3307番へレプリケーションしているので、
3307番でも同様の結果になりました。
では、ここで3306番MySQLをとめてから、再度同じクエリを実行してみましょう。
3306番停止
[root@cent7-mysql57-2 ~]# kill 4039 ###3306 MySQL停止
クエリ再実行
[root@cent7-mysql57-1 ~]# java routertest
すると・・・?
3308番MySQLにて
mysql-3308> select * from test.t1; +------+------------------------+ | col1 | col2 | +------+------------------------+ | 1 | insert from app server | +------+------------------------+ 1 row in set (0.00 sec)
確かに処理は2つめのdestinationに移動していますね。
ちなみに、この後ただ3306番MySQLを起動しても、
処理は3308番に行ったままだったので、
3306番に処理を戻したければmysqlrouterプロセスの再起動が必要になります。
通常のルーティングについてはこんなところでしょうか。
MySQL Fabric Cache Pluginの方も書きたかったのですが、
大分分量も多くなってしまってますし(著者も疲れましたし笑)、
また次回書きたいと思います。
では。
====================================
MySQL Router 基本ルーティング編
MySQL Router Fabricルーティング編