アーカイブ

MariaDB Galera Clusterを試す (1)

みなさんこんにちは。研究所の鷲北です。

最近、クラスタDBに興味があって調べていたのですが、どうもMySQLのクラスタ版はインストールが難しいなと困っていたところ、MariaDBのクラスタ版、MariaDB Galera Cluster がRCになったというニュースを目にしたので、試してみようと思い立ちました。というわけで、インストールの方法と簡単なベンチマーク結果を当ブログでご紹介したいと思います。

MariaDB Galera Clusterの特長は、こちらのページに詳しく載っていますのでぜひご覧ください。

簡単にまとめると次のようになります。

  • Galera Replicationが複数のRDBMをレプリケーションするwsrep APIを提供し、同期をとります
  • 完全同期型であるため、すべてのノードがアクティブかつマスターとなります
  • クラスターノードのどれに対してもリード/ライトが可能です
  • ノードの追加/削除は自動で行えます
  • クライアント接続は通常のMySQLとなんら変わりなく使えます

なお、今回は以下の環境を前提とさせていただいております。

  • 多数のサーバをネットワークでつなぐため、さくらのクラウドを使用
  • サーバスペックはプラン1(仮想1コア、2GBメモリ、20GB HDD)、CentOS 6.3
  • WordPressが動く程度の環境を構築することを目指す

ネットワーク構成

DBをクラスタ構成にしただけでは役に立ちませんので、処理を分散するために必要な機構も後で追加できるようにネットワークを構成しておくことにします。またアプリケーションとしてWordPressを動かすため、Webサーバも導入します。ネットワークの頭にNATルータをおいて、スイッチを介してサーバ群を配置することにします。構成図は以下の図の通りになりますが、最初はMariaDB Glera Clusterに集中するために、クラスタサーバ(3台)とそれらを接続するルータ兼NATサーバの4台をセットアップします。

ネットワーク構成(1)

ネットワーク構成(1)

NATルータの準備

NATルータはインターフェースを2つもち、eth0がグローバル、eth1がローカルスイッチに接続されています。NAT設定はお好み次第ですが、たとえばiptablesを使った場合は次のようになります。

  1. /etc/sysctl.conf の net.ipv4.ip_forward を 1 に変更し、sysctl -p を実行する
  2. /etc/sysconfig/iptables を以下のように設定し、iptables を再起動する
*nat
:PREROUTING ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A POSTROUTING -s 192.168.0.0/24 -o eth0 -j MASQUERADE
COMMIT
#
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
COMMIT

この例は最低限のNAT設定のみですので、セキュリティのためのフィルタ設定は必要に応じて設定してください。

DBサーバの準備とMariaDBのインストール

次にDBサーバを用意します。1台目は、図にならってdb1と呼びます。回線契約は不要で、ローカルスイッチに接続したCentOS 6.3、特にMySQLがインストールされていないものを用意してください。さくらのクラウドを使用する場合、アーカイブで提供しているCentOS 6.3 64bit版パッケージで問題なくご利用いただけます。eth0はNATルータが接続されているローカルスイッチと同じ 192.168.0.0/24 へ接続します。db1のIPアドレスは192.168.0.21です。GATEWAYはNATルータ 192.168.0.1 に向けます。DNS等はNATルータが中継してくれますので、その他の設定は変更せずに動作するはずです。

  • /etc/sysconfig/network
NETWORKING=yes
NETWORKING_IPV6=no
HOSTNAME=db1
GATEWAY=192.168.0.1
  • /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
BOOTPROTO="static"
ONBOOT="yes"
TYPE="Ethernet"
HWADDR=9c:a3:ba:xx:xx:xx
NETMASK=255.255.255.0
BROADCAST=192.168.0.255
IPADDR=192.168.0.21
NETWORK=192.168.0.0

起動したらネットワークが正常に動作することを確認します。それからyum updateを実行し、カーネル等を最新版にしておいてください。

MariaDBのもっとも簡単なインストール方法は、yumを使うことです。MariaDBの本家サイトにはリポジトリ・ジェネレータが用意されていて、各種ディストリビューション用の最新リポジトリを生成してくれます。これを使えばすぐにインストール準備が整います。今回はCentOS 6.3、64bit版、MariaDB5.5(2013年2月13日時点では、Galera Clusterはまだ5.5.8aのため)を選択します。すると生成されたリポジトリが画面下部に表示されますので、これをコピーして /etc/yum.repos.d/MariaDB.repo という名前でセーブします。

リポジトリ・ジェネレータ

リポジトリ・ジェネレータ

リポジトリを作成したら、以下のコマンドを実行してインストールします。

[root@db1 ~]# yum install MariaDB-Galera-server MariaDB-client galera

MariaDB-serverはmysqldに相当するサーバパッケージのクラスタ対応版、MariaDB-clientはmysqlやmysqladmin等のアクセスツール、galeraはクラスタを実装するライブラリ群となります。

ちなみにクラスタではなく、シングルサーバのMariaDBを使いたい場合は

[root@db1 ~]# yum install MariaDB-server MariaDB-client

と指定すればOKです。

設定ファイルの準備

MariaDB Galera Clusterを起動するためには、クラスタ設定のための指定をいろいろとしておく必要があります。設定は /etc/my.cnf.d/server.cnf ファイルの [mysqld] セクションに記述します。インストール直後は何も書かれていないので、こちらに必要な設定を追記していきます。

# this is only for the mysqld standalone daemon
[mysqld]
wsrep_cluster_name=DBCLUSTER
wsrep_cluster_address=gcomm://192.168.0.22
wsrep_node_address=192.168.0.21
wsrep_provider='/usr/lib64/galera/libgalera_smm.so'
wsrep_sst_method=rsync
wsrep_slave_threads=4
default_storage_engine=InnoDB
binlog_format=ROW
innodb_autoinc_lock_mode=2
innodb_locks_unsafe_for_binlog=1

設定ファイルの内容は次の通りです。

  • wsrep_cluster_name
    クラスタ名の識別子。クラスタごとに任意の名前を付けてください。
  • wsrep_cluster_address
    参加するクラスタ・ノードのIPアドレスを指定します。最初のノードでは「gcomm://」とし、IPアドレスを指定しません。ただし、設定ファイルに空のアドレス指定をすると再起動のたびに独立したノードを立ち上げてしまいます。これはよろしくないので、ノード起動時にコマンドラインで指定することとし、設定ファイルには隣のノードを明示しておきます。なお、ここで指定するノードが起動していないとき(この場合は192.168.0.22)はエラーになるので注意が必要です。
  • wsrep_node_address
    自分のノードアドレスを指定します。明示しないと、最初のNICについているアドレスが自動的に採用されます。指定しなくてもよいのですが、明示しておくことをお勧めします。
  • wsrep_provider
    ライブラリファイルをfull pathで指定します。
  • wsrep_sst_method
    SSTはState Snapshot Transferといって、ノードをクラスタに追加するときにデータコピーを行う方法を指定します。ここではrsyncを指定しています。
  • wsrep_slave_threads
    スレッド数を指定します。マニュアルによればスレッド数の目安は (1) CPUコア数の2倍 (2) 書き込み接続数の1/4、とあります。ここでは適当に4としています。
  • DBエンジン設定
    以下の4つの設定は必須です。他のDBエンジンやモードでは動作に問題が生じる可能性があるので気を付けてください。
default_storage_engine=InnoDB
binlog_format=ROW
innodb_autoinc_lock_mode=2
innodb_locks_unsafe_for_binlog=1

初期ノードを起動する

準備が整ったらいよいよ初期ノードを起動します。大前提として、他のノードは起動していないことを確認してください。最初のノードを起動するときは、自分自身が初期ノードとなることを明示する必要があります。起動コマンドは次のようになります。

[root@db1 ~]# service mysql start --wsrep_cluster_address=gcomm://

繰り返しになりますが、もしオプションを付与しないと隣のノードを探しに行ってしまいエラーになります。すでにクラスタが構成されているときは問題ありませんが、初期ノード起動時には失敗になりますので注意してください。さて、問題なく起動できたらデータベースのテストをしてみます。mysqlコマンドでデータベースに接続してみましょう。

[root@db1 ~]# mysql
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 797
Server version: 5.5.28a-MariaDB MariaDB Server, wsrep_23.7rc1.rXXXX

Copyright (c) 2000, 2012, Oracle, Monty Program Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]>

SQLサーバとしては、問題なく動作しているようです。クラスタとしてはどうでしょうか。「show status like ‘wsrep_%’;」と入力することで、Galera関連の情報を確認することができます。

MariaDB [(none)]> show status like 'wsrep_%';
+----------------------------+--------------------------------------+
| Variable_name              | Value                                |
+----------------------------+--------------------------------------+
| wsrep_local_state_uuid     | bd57f11b-6f59-11e2-0800-b563a50f795a |
| wsrep_protocol_version     | 4                                    |
| wsrep_last_committed       | 611                                  |
| wsrep_replicated           | 0                                    |
| wsrep_replicated_bytes     | 0                                    |
| wsrep_received             | 4                                    |
| wsrep_received_bytes       | 448                                  |
| wsrep_local_commits        | 0                                    |
| wsrep_local_cert_failures  | 0                                    |
| wsrep_local_bf_aborts      | 0                                    |
| wsrep_local_replays        | 0                                    |
| wsrep_local_send_queue     | 0                                    |
| wsrep_local_send_queue_avg | 0.000000                             |
| wsrep_local_recv_queue     | 0                                    |
| wsrep_local_recv_queue_avg | 0.000000                             |
| wsrep_flow_control_paused  | 0.000000                             |
| wsrep_flow_control_sent    | 0                                    |
| wsrep_flow_control_recv    | 0                                    |
| wsrep_cert_deps_distance   | 0.000000                             |
| wsrep_apply_oooe           | 0.000000                             |
| wsrep_apply_oool           | 0.000000                             |
| wsrep_apply_window         | 0.000000                             |
| wsrep_commit_oooe          | 0.000000                             |
| wsrep_commit_oool          | 0.000000                             |
| wsrep_commit_window        | 0.000000                             |
| wsrep_local_state          | 4                                    |
| wsrep_local_state_comment  | Synced                               |
| wsrep_cert_index_size      | 0                                    |
| wsrep_causal_reads         | 0                                    |
| wsrep_incoming_addresses   | 192.168.0.21:3306                    |
| wsrep_cluster_conf_id      | 3                                    |
| wsrep_cluster_size         | 1                                    |
| wsrep_cluster_state_uuid   | bd57f11b-6f59-11e2-0800-b563a50f795a |
| wsrep_cluster_status       | Primary                              |
| wsrep_connected            | ON                                   |
| wsrep_local_index          | 0                                    |
| wsrep_provider_name        | Galera                               |
| wsrep_provider_vendor      | Codership Oy <info@codership.com>    |
| wsrep_provider_version     | 23.2.2(r137)                         |
| wsrep_ready                | ON                                   |
+----------------------------+--------------------------------------+
40 rows in set (0.00 sec)

チェックポイントは wsrep_local_state_comment が Synced になっていることと、wsrep_incoming_addresses に自分のノードアドレスが入っていることです。これで自分が初期ノードとして正しく動作していることが確認できます。

初期ノードが起動したら、ここでrootアカウントに正しい権限とパスワードを設定しましょう。localhostおよびリモートからアクセスできるよう、次のように設定します。パスワードは適切に割り当ててください。これは後ほど何度も使いますのできちんと記録しておいてください。

grant all privileges on *.* to root@'%' identified by 'DB_PASS' with grant option;
grant all privileges on *.* to root@localhost identified by 'DB_PASS' with grant option;

2台目、3台目のノードを追加する

初期ノードが起動したら、次のノードを追加します。ノードの追加は非常に簡単です。初期ノード・サーバと同じように設定を行い、設定ファイルをわずかに変更するだけでよいからです。さくらのクラウドを使っている場合、方法は2つあります。同じ手順を繰り返すか、db1をコピーしてdb2を作るかです。せっかくクラウドを使っているのですからコピーすることを強くお勧めします。

  1. いったんdb1を停止します
  2. コンパネからdb1のクローンを作成します。ディスクはコピーを選択します
  3. コピーが完了したらdb1を起動します
  4. db2も起動します
  5. MACアドレス設定が異なるためネットワークに繋がりません。コンソールのモニタからログインしてifconfig-eth0を修正します
  6. 新しいMACアドレスはコンソールのNIC欄から確認できます
  7. リブートすればdb2が完成します
モニタからの操作の例

モニタからの操作の例

ちなみに設定変更が必要な個所は以下の2つです。

  • /etc/sysconfig/network
NETWORKING=yes
NETWORKING_IPV6=no
HOSTNAME=db2
GATEWAY=192.168.0.1
  • /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
BOOTPROTO="static"
ONBOOT="yes"
TYPE="Ethernet"
HWADDR=9c:a3:ba:xx:xx:xx
NETMASK=255.255.255.0
BROADCAST=192.168.0.255
IPADDR=192.168.0.22
NETWORK=192.168.0.0

サーバが起動したら、MariaDBの設定を行います。ファイルのインストールは完了していますが、起動はしていないはずです(初期設定ではchkconfigがoffになっています)。まず/etc/my.cnf.d/server.confを変更します。

# this is only for the mysqld standalone daemon
[mysqld]
wsrep_cluster_name=DBCLUSTER
wsrep_cluster_address=gcomm://192.168.0.21
wsrep_node_address=192.168.0.22
wsrep_provider='/usr/lib64/galera/libgalera_smm.so'
wsrep_sst_method=rsync
wsrep_slave_threads=4
default_storage_engine=InnoDB
binlog_format=ROW
innodb_autoinc_lock_mode=2
innodb_locks_unsafe_for_binlog=1

変更点は2つ、wsrep_cluster_addressを初期ノードである192.168.0.21にすること、wsrep_node_addressを自分自身である192.168.0.22にすることです。設定ファイルが準備できたらMariaDBサーバを起動します。db2の起動時には、すでにdb1が起動しているので初期ノードとしてオプションを指定する必要はありません。

[root@db2 ~]# service mysql start
Starting MySQL..... SUCCESS!

起動できたら、MariaDBサーバに接続してみましょう。先ほどと同じ要領で、mysqlコマンドでつなぎます。rootアカウントとパスワードを設定しているので、入力を忘れないようにしてください。そして先ほどと同じように、「show status like ‘wsrep_%’;」を実行してみます。

[root@db2 ~]# mysql -u root -p
Enter password:
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 44
Server version: 5.5.28a-MariaDB MariaDB Server, wsrep_23.7rc1.rXXXX

Copyright (c) 2000, 2012, Oracle, Monty Program Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> show status like 'wsrep_%';
+----------------------------+--------------------------------------+
| Variable_name              | Value                                |
+----------------------------+--------------------------------------+
| wsrep_local_state_uuid     | bd57f11b-6f59-11e2-0800-b563a50f795a |
| wsrep_protocol_version     | 4                                    |
| wsrep_last_committed       | 611                                  |
| wsrep_replicated           | 0                                    |
| wsrep_replicated_bytes     | 0                                    |
| wsrep_received             | 2                                    |
| wsrep_received_bytes       | 196                                  |
| wsrep_local_commits        | 0                                    |
| wsrep_local_cert_failures  | 0                                    |
| wsrep_local_bf_aborts      | 0                                    |
| wsrep_local_replays        | 0                                    |
| wsrep_local_send_queue     | 0                                    |
| wsrep_local_send_queue_avg | 0.000000                             |
| wsrep_local_recv_queue     | 0                                    |
| wsrep_local_recv_queue_avg | 0.000000                             |
| wsrep_flow_control_paused  | 0.000000                             |
| wsrep_flow_control_sent    | 0                                    |
| wsrep_flow_control_recv    | 0                                    |
| wsrep_cert_deps_distance   | 0.000000                             |
| wsrep_apply_oooe           | 0.000000                             |
| wsrep_apply_oool           | 0.000000                             |
| wsrep_apply_window         | 0.000000                             |
| wsrep_commit_oooe          | 0.000000                             |
| wsrep_commit_oool          | 0.000000                             |
| wsrep_commit_window        | 0.000000                             |
| wsrep_local_state          | 4                                    |
| wsrep_local_state_comment  | Synced                               |
| wsrep_cert_index_size      | 0                                    |
| wsrep_causal_reads         | 0                                    |
| wsrep_incoming_addresses   | 192.168.0.22:3306,192.168.0.21:3306  |
| wsrep_cluster_conf_id      | 4                                    |
| wsrep_cluster_size         | 2                                    |
| wsrep_cluster_state_uuid   | bd57f11b-6f59-11e2-0800-b563a50f795a |
| wsrep_cluster_status       | Primary                              |
| wsrep_connected            | ON                                   |
| wsrep_local_index          | 0                                    |
| wsrep_provider_name        | Galera                               |
| wsrep_provider_vendor      | Codership Oy <info@codership.com>    |
| wsrep_provider_version     | 23.2.2(r137)                         |
| wsrep_ready                | ON                                   |
+----------------------------+--------------------------------------+
40 rows in set (0.00 sec)

wsrep_incoming_address が2つになっていれば成功です。これで2ノードのクラスタが完成しました。

3台目のノードであるdb3も、同じ要領で追加すればOKです。上記のようにチェックして、3ノード見えていれば成功です。

データの読み書きを試す

さて、設定上はクラスタが構成できたように見えますが、本当にデータの共有ができているのでしょうか。データベースやテーブルを作成して、ノード間でデータ共有ができているか確かめてみましょう。

まずdb1の方で、テスト用のデータベースとテーブルを作成してみます。

[root@db1 ~]# mysql -u root -p
Enter password:
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 1036
Server version: 5.5.28a-MariaDB MariaDB Server, wsrep_23.7rc1.rXXXX

Copyright (c) 2000, 2012, Oracle, Monty Program Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> create database testdb;
Query OK, 1 row affected (0.00 sec)

MariaDB [(none)]> use testdb;
Database changed
MariaDB [testdb]> create table tbl (
    -> name text,
    -> phone text,
    -> addr text
    -> );
Query OK, 0 rows affected (0.01 sec)

MariaDB [testdb]> insert into tbl ( name, phone, addr )
    -> values ( 'north', '012-345-6789', 'Tokyo/Japan' );
Query OK, 1 row affected (0.00 sec)

MariaDB [testdb]>

続いてdb2の方で、作成したデータベースとテーブルにアクセスしてみます。db2では何の操作もしていませんが、Galera Replicationが自動的に同期をとってくれているので、きちんと読みだすことができます。

[root@db2 ~]# mysql -u root -p
Enter password:
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 451
Server version: 5.5.28a-MariaDB MariaDB Server, wsrep_23.7rc1.rXXXX

Copyright (c) 2000, 2012, Oracle, Monty Program Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> use testdb;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
MariaDB [testdb]> select * from tbl;
+-------+--------------+-------------+
| name  | phone        | addr        |
+-------+--------------+-------------+
| north | 012-345-6789 | Tokyo/Japan |
+-------+--------------+-------------+
1 row in set (0.00 sec)

MariaDB [testdb]>

ノードのアップ/ダウン

MariaDB Galera Clusterでは、ノードのアップ/ダウンの検出と制御は全自動で行われます。あるノードがダウンすると、それは自動的に取り除かれ、他のノードは素知らぬふりをしながら動作し続けます。どのノードがアクティブであるかはwsrep_incoming_addressesを確認することでわかります。

ダウンしたノードをアップさせたり、新規に追加したい場合は、参照したいノードをwsrep_cluster_addressに指定して起動します。アップしたノードはそのノードから情報を受け取り、クラスタに参加します。いったん参加に成功すれば、あとはクラスタの一員として動作し続けることができます。これらの動作も自動的に行われます。管理上気を付けなければならないのは、参照するノードが起動していることを確認する必要があるということです。

すべてのノードがダウンしてしまった場合に、クラスタを復旧させる場合はどうでしょうか。初期ノードの起動のところで触れたとおり、rsrep_cluster_addressに空アドレスを指定して起動します。こうすれば参照したいノードを探しに行かず、自らが持っているデータベースを元に初期ノードとして新しいクラスタを生成します。クラスタがダウンしてしまったときに、急いで復旧させたいとき、configファイルを書き換えたり、問題がないかを確認するのは運用上問題になりかねません。通常はノードのアップ/ダウンを想定して隣のノードを参照するようにconfigを設定しておき、クラスタの起動の時にはコマンドラインから–wsrep_cluster_addressオプションで空アドレスを明示するのがよいようです。

おわりに

クラウド環境であれば、ノードの数はどんどん増やしていくことができます。IPアドレスを次々に変えてノードサーバを立ち上げていくだけでよいからです。しかし、DBをクラスタ化しただけでは、サーバが増えたことによるオーバーヘッドが増しただけで、分散化や冗長化などのメリットは享受できません。それらの設定はMariaDB Galera Clusterだけでは実現できないのです。そこで次回は、LVSを使って処理の分散化を行ってみたいと思います。

参考リンク

7 comments to MariaDB Galera Clusterを試す (1)

Leave a Reply

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

  

  

  

ERROR: si-captcha.php plugin: GD image support not detected in PHP!

Contact your web host and ask them to enable GD image support for PHP.

ERROR: si-captcha.php plugin: imagepng function not detected in PHP!

Contact your web host and ask them to enable imagepng for PHP.