IDCFクラウド RDBマルチマスターを試してみた
(2018.7.26追記)
この記事で使用したIDCFクラウド RDBは、2016年8月に廃止された旧サービスのものですので、ご注意ください。
その後、IDCFクラウドのRDBは、2018年6月に新たな形で(再)リリースされています。
・IDCF Cloud RDB
https://www.idcf.jp/cloud/rdb/
(2018.7.26追記ここまで)
前回の記事「IDCFクラウド RDBを試してみた」では、IDCFクラウドRDBで、1ノードだけ起動してDBアクセスを確認しました。
今回は、最大のウリだと思われるマルチマスター機能を試してみます。
※僕は、IDCFクラウドに限らず、マルチマスターDBを試すのは初めてです。
・IDCFクラウド RDB
http://www.idcf.jp/cloud/rdb/
以下は、2015年8月18日時点の情報です。
構築する構成
今回構築する環境は、IDCFクラウド内で次のような構成とします。
- クライアント: 仮想マシン x 1
- マルチマスターDBサーバー: RDB 3ノード
ここで「ノード」は、マルチマスターのDBサーバーを構成するひとつひとつのサーバーインスタンスをを表します。
クライアント用サーバー、マルチマスターDBサーバーの構築
前回の記事「IDCFクラウド RDBを試してみた」と同様に、同一ネットワーク上にクライアント用サーバーとDBサーバーを構築します。
マルチマスターDBサーバーを構築する際は、RDBの「データベースの作成」で、ノード数3以上を指定します。
前回1ノードを作成した際は、作成指示後、完了するまで13分程度かかりましたが、3ノードでは15分30秒程度でした。
何回か試しましたが、だいたい同じぐらいの時間です。
-- 「イベント」表示より 2015-08-18 16:06:40 JST INFO Create instance job started ... 2015-08-18 16:22:15 JST INFO All Tasks for current job completed successfully --
「アクセス情報」で3つのノードの情報が確認できます。
DBサーバーへのアクセス先については、それぞれのノードごとにアクセス先のプライベートDNSが表示されるのでメモしておきます。
今回のプライベートDNSは次のとおりです。
- ノード1: rdbtest4_5461_private.rdb.jp-east.idcfcloud.com
- ノード2: rdbtest4_1494_private.rdb.jp-east.idcfcloud.com
- ノード3: rdbtest4_2798_private.rdb.jp-east.idcfcloud.com
※ノード1,2,3はこの記事で便宜上つけたもので、IDCFクラウドで設定できるものではありません。
クライアント用サーバー上のmysqlコマンドで、それぞれのノードにDBアクセスしてみます。
(ノード1にアクセス) # mysql -h rdbtest4_5461_private.rdb.jp-east.idcfcloud.com \ -u rdbtestuser -p (ノード2にアクセス) # mysql -h rdbtest4_1494_private.rdb.jp-east.idcfcloud.com \ -u rdbtestuser -p (ノード3にアクセス) # mysql -h rdbtest4_2798_private.rdb.jp-east.idcfcloud.com \ -u rdbtestuser -p
ノード1で、テーブルを作成し、データを投入してみます。
(ノード1) mysql> use rdbtestdb; mysql> create table innodb_table (id int, name varchar(20)) engine = InnoDB default charset=utf8; mysql> insert into innodb_table values (0, '札幌'); mysql> insert into innodb_table values (1, '旭川'); mysql> commit; mysql> select * from innodb_table where name = '札幌'; +------+--------+ | id | name | +------+--------+ | 0 | 札幌 | +------+--------+ 1 row in set (0.00 sec)
ノード2,3のmysqlコマンドで、検索してみます。
(ノード2) mysql> use rdbtestdb; mysql> show tables; +---------------------+ | Tables_in_rdbtestdb | +---------------------+ | innodb_table | +---------------------+ 1 row in set (0.00 sec) mysql> select * from innodb_table where name = '札幌'; +------+--------+ | id | name | +------+--------+ | 0 | 札幌 | +------+--------+ 1 row in set (0.00 sec)
ほかのノードで追加したデータを参照できています。
続いて、ノード2でデータを追加します。
(ノード2) mysql> insert into innodb_table values (2, '函館'); mysql> commit;
ノード1で検索してみます。
(ノード1) mysql> select * from innodb_table; +------+--------+ | id | name | +------+--------+ | 0 | 札幌 | | 1 | 旭川 | | 2 | 函館 | +------+--------+ 1 row in set (0.00 sec)
複数のノードに対して書き込み、読み込みができることが確認できました!
DBサーバーへのアクセス分散
DBアクセスの分散方法
IDCFクラウドRDBでは、複数のノードに対して書き込み、読み込み可能なマルチマスターDBサーバー環境が提供されます。
しかし、DBへのアクセスを自動的に分散してくれるようなしくみは、IDCFクラウドでは提供されていないため、クライアント側でどのノードにアクセスするかを明示的に指定する必要があります。
マルチマスターDBへのDBアクセスを負荷分散するには、さまざまな方法が考えられますが、各クライアントアプリが動作するサーバー上にHAProxyを導入する方法を採用することが多いようです。
(参考)
・MySQL互換でマルチマスタ同期レプリケーションが可能なPercona XtraDB Clusterで手軽に冗長構成RDBを構築
https://qiita.com/nownabe/items/462f46f2702ce1ad4b6d
各クライアントアプリはサーバー上で動作するHAProxyにアクセスし、HAProxyは、指定した負荷分散アルゴリズムに従って、登録されているバックエンド・ノードにアクセスを振り分けます。
構成は次のようなイメージとなります。
HAProxyの設定
上記参考記事を参考に、HAProxyをインストール、設定します。
以下、クライアント用の仮想マシン上で作業します。
・HAProxyヘルスチェック用ユーザーの作成
DBにHAProxyヘルスチェック用ユーザーを作成します。
アクセス元は、同一ネットワーク内に制限します。
mysql> grant usage on *.* to 'haproxy'@'10.5.0.0/255.255.252.0';
・HAProxyのインストール
まず、yumリポジトリにEPELを追加します。
# wget http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm # rpm -ivh epel-release-6-8.noarch.rpm
デフォルトでは無効としておく場合は enabled=1 を 0 とします。
# vi /etc/yum.repos.d/epel.repo -- enabled=0 --
HAProxyをインストールします。
# yum --enablerepo=epel install haproxy
・HAProxyの設定
Configは、上記参考記事内に記載のある、Gistに公開されているものをダウンロードします。
# cp -p /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.default # curl -o /etc/haproxy/haproxy.cfg \ https://gist.githubusercontent.com/nownabe/27ffdd8fed6a3f1707e8/raw/14d7f25fbd76c554c451610f2ac033bf809297bf/haproxy.cfg
今回の環境用に修正します。
以下の設定で、HAProxyはこのサーバー自身(localhost)のTCP/3306へのDBアクセスを、server行で指定した3つのノード(バックエンド)にラウンドロビンで振り分けます。
# vi /etc/haproxy/haproxy.cfg -- ... listen hastats *:8080 // Statsページのポートを80から8080に変更 mode http maxconn 64 timeout connect 5000 timeout client 10000 timeout server 10000 stats enable stats show-legends stats uri /haproxy?hastats // StatsページのURL stats auth admin:p@ssw0rd // StatsページのID,パスワード listen mysql *:3306 mode tcp option mysql-check user haproxy balance roundrobin // 分散対象のバックエンドをRDBノードに変更 server node-01 rdbtest4_5461_private.rdb.jp-east.idcfcloud.com check server node-02 rdbtest4_1494_private.rdb.jp-east.idcfcloud.com check server node-03 rdbtest4_2798_private.rdb.jp-east.idcfcloud.com check --
またHAProxy StatsのWebページにアクセスするため、IDCFクラウドコンソールのファイアウォール、ポートフォワード設定で、クライアント用サーバーへのTCP/8080 へのアクセス許可ルールを追加します。
・HAProxyを起動
# /etc/init.d/haproxy start
HAProxy経由のアクセス確認
以下のコマンドで、アクセスしたノードのIPアドレスが表示されます。
# mysql -u rdbtestuser -h 127.0.0.1 -p \ -e "show variables like 'wsrep_provider_options'" | tail -1 | awk '{print $4}' 10.5.0.117;
このコマンドを何度か繰り返すと、ラウンドロビンで順にアクセスしていることがわかります。
10.5.0.74; 10.5.0.95; 10.5.0.117; ...
WebブラウザでHAProxy StatsのWebページにアクセスします。
http://<クライアント用サーバーのグローバルIPアドレス>:8080/haproxy?hastats
「Sessionss Total」を見ると、各ノードに均等にアクセスしたことがわかります。
mysqlコマンドでSQLクエリを実行して、正しい結果が返ってくることを確認します。
# mysql -h 127.0.0.1 -u rdbtestuser -p rdbtestdb mysql> select * from innodb_table where name = '札幌'; +------+--------+ | id | name | +------+--------+ | 0 | 札幌 | +------+--------+ 1 row in set (0.00 sec)
HAProxyを使って、クライアントからのDBアクセスを複数ノードに振り分けることができました!
ノードの追加・削除
続いて、ノードの追加、削除を試してみます。
ノードの追加
クラウドコンソールでDBサーバーを選択し、「操作」から「ノード追加」を選択します。
ノード追加中も問題なくアクセスできることを確認します。
# mysql -u rdbtestuser -h 127.0.0.1 -p \ -e "show variables like 'wsrep_provider_options'" | tail -1 | awk '{print $4}' 10.5.0.117;
ノード追加が完了し、4ノードとなりました。
追加処理が終了するまで、15分30秒程度かかりました。
-- 「イベント」表示より 2015-08-18 17:02:37 JST INFO Add Node Create Instance Job Started ... 2015-08-18 17:18:10 JST INFO All Tasks for current job completed successfully --
クラウドコンソールで追加ノードを確認し、プライベートDNSをメモします。
ここでは、rdbmm1_5100_private.rdb.jp-east.idcfcloud.com が追加されました。
追加したノードにもDBアクセスするよう、HAProxyのバックエンドエントリーに新しいノードのプライベートDNSを追加します。
# vi /etc/haproxy/haproxy.cfg -- ... server node-01 rdbmm1_7534_private.rdb.jp-east.idcfcloud.com check server node-02 rdbmm1_1920_private.rdb.jp-east.idcfcloud.com check server node-03 rdbmm1_3823_private.rdb.jp-east.idcfcloud.com check server node-04 rdbmm1_5100_private.rdb.jp-east.idcfcloud.com check --
HAProxyをreloadして反映させます。
# /etc/init.d/haproxy reload
mysqlコマンドを使用して、HAProxy経由でアクセスを繰り返します。
4ノードに順にアクセスしていることがわかります。
# mysql -u rdbtestuser -h 127.0.0.1 -p \ -e "show variables like 'wsrep_provider_options'" | tail -1 | awk '{print $4}' 10.5.0.41; 10.5.1.4; 10.5.0.207; 10.5.0.241; 10.5.0.41; 10.5.1.4; 10.5.0.207; 10.5.0.241;
HAProxyのStatsを確認します。
http://<クライアント用サーバーのグローバルIPアドレス>:8080/haproxy?hastats
「Sessionss Total」を見ると、4ノードに均等にアクセスしたことがわかります。
ノードの削除
クラウドコンソールでDBサーバーを選択し、「操作」から「ノード削除」を選択します。
ノード削除中も問題なくアクセスできることを確認します。
# mysql -u rdbtestuser -h 127.0.0.1 -p \ -e "show variables like 'wsrep_provider_options'" | tail -1 | awk '{print $4}' 10.5.0.117;
追加処理が終了するまで、6分程度かかりました。
-- 「イベント」表示より 2015-08-18 17:29:34 JST INFO Container engine configuration started ... 2015-08-18 17:35:20 JST INFO All Tasks for current job completed successfully --
HAProxyのStatsを確認します。
http://<クライアント用サーバーのグローバルIPアドレス>:8080/haproxy?hastats
削除されたノードnode-02のセルの背景が赤(DOWN)で表示され、そのノードへのセッション数が少なくなっていることがわかります。
まとめ
IDCFクラウドRDBのマルチマスター機能を試してみて、以下のことがわかりました。
- かんたんにマルチマスターDBを構築できる。
- HAProxyを使って、クライアントからのDBアクセスを複数ノードに振り分けることができる。
- HAProxyにより、ノード追加・削除時や、(ノードを停止する手段がないので今回は確認できなかったが)ノード障害時も、DBアクセスを継続できる。
※ノード障害時に、DBアクセスがどれぐらいの時間エラーするかは、HAProxyのタイムアウト、チェック間隔、リトライ等の設定や、アプリケーションのDB接続方法によると思います。
(関連記事)
・IDCFクラウド RDBを試してみた
https://inaba-serverdesign.jp/blog/20150731/idcfcloud_rdb.html
・IDCFクラウドRDBサービスの廃止について思うこと。
https://inaba-serverdesign.jp/blog/20160531/idcf_rdb_abolished.html