IDCFクラウド RDBマルチマスターを試してみた

(2016.5.31追記)
IDCFクラウドRDBサービスは、2016年8月31日をもって廃止することが通知されました。
(2016.5.31追記ここまで)

前回の記事「IDCFクラウド RDBを試してみた」では、IDCFクラウドRDBで、1ノードだけ起動してDBアクセスを確認しました。
今回は、最大のウリだと思われるマルチマスター機能を試してみます。

※僕は、IDCFクラウドに限らず、マルチマスターDBを試すのは初めてです。

・IDCFクラウド RDB
http://www.idcf.jp/cloud/rdb/

以下は、2015年8月18日時点の情報です。
画像はクリックすると大きく表示されます。

isd構築する構成

今回構築する環境は、IDCFクラウド内で次のような構成とします。

  • クライアント: 仮想マシン x 1
  • マルチマスターDBサーバー: RDB 3ノード

idcfrdbmm_design1
 

ここで「ノード」は、マルチマスターのDBサーバーを構成するひとつひとつのサーバーインスタンスをを表します。

isdクライアント用サーバー、マルチマスターDBサーバーの構築

前回の記事「IDCFクラウド RDBを試してみた」と同様に、同一ネットワーク上にクライアント用サーバーとDBサーバーを構築します。

マルチマスターDBサーバーを構築する際は、RDBの「データベースの作成」で、ノード数3以上を指定します。

rdbmm_createdb1
 

前回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つのノードの情報が確認できます。

rdbmm_createdb2
 

DBサーバーへのアクセス先については、それぞれのノードごとにアクセス先のプライベートDNSが表示されるのでメモしておきます。

rdbmm_createdb3
 

今回のプライベート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)

 

複数のノードに対して書き込み、読み込みができることが確認できました!

isdDBサーバーへのアクセス分散

DBアクセスの分散方法

IDCFクラウドRDBでは、複数のノードに対して書き込み、読み込み可能なマルチマスターDBサーバー環境が提供されます。
しかし、DBへのアクセスを自動的に分散してくれるようなしくみは、IDCFクラウドでは提供されていないため、クライアント側でどのノードにアクセスするかを明示的に指定する必要があります。
マルチマスターDBへのDBアクセスを負荷分散するには、さまざまな方法が考えられますが、各クライアントアプリが動作するサーバー上にHAProxyを導入する方法を採用することが多いようです。

(参考)
・MySQL互換でマルチマスタ同期レプリケーションが可能なPercona XtraDB Clusterで手軽に冗長構成RDBを構築
https://qiita.com/nownabe/items/462f46f2702ce1ad4b6d

各クライアントアプリはサーバー上で動作するHAProxyにアクセスし、HAProxyは、指定した負荷分散アルゴリズムに従って、登録されているバックエンド・ノードにアクセスを振り分けます。
構成は次のようなイメージとなります。

idcfrdbmm_design2
 

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

rdbmm_add_node_stats
 

「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アクセスを複数ノードに振り分けることができました!

isdノードの追加・削除

続いて、ノードの追加、削除を試してみます。

ノードの追加

クラウドコンソールでDBサーバーを選択し、「操作」から「ノード追加」を選択します。

rdbmm_add_node
 

ノード追加中も問題なくアクセスできることを確認します。

 # 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ノードとなりました。

rdbmm_add_node2
 

追加処理が終了するまで、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

rdbmm_add_node_stats
 

「Sessionss Total」を見ると、4ノードに均等にアクセスしたことがわかります。

ノードの削除

クラウドコンソールでDBサーバーを選択し、「操作」から「ノード削除」を選択します。

rdbmm_del_node
 

ノード削除中も問題なくアクセスできることを確認します。

 # 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

rdbmm_del_node_stats
 

削除されたノードnode-02のセルの背景が赤(DOWN)で表示され、そのノードへのセッション数が少なくなっていることがわかります。

isdまとめ

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
 

Follow me!