MySQL Clusterを検証する機会があったので、導入手順のメモ

タイトルのとおりなんですが。

結果、検証後に導入することにはならなかったのですが、せっかく作ったんだしこのまま放置していては忘れてしまいそうなので、一応こちらの方にメモとして残しておきます。

MySQL Clusterとは

MySQL Clusterとは非共有システム(シェアードナッシングシステム)でのMySQLデータベースのクラスタ化を可能にします。サーバーを追加することでMySQLデータをスケールアウトすることが可能であり、単一障害点(SPOF)を持たないように構築することで、高可用性のMySQL環境を実現します。

MySQL ClusterはNDBと呼ばれるin-memoryストレージエンジンで標準のMySQLサーバーを統合します。クラスタ化されたデータは、データノードが保持しています。ノードと言うのはMySQL-Clusterの場合プロセスを意味します。

ノードの種類には以下のものが有ります。最低でもそれぞれ1つ以上は起動していないとMySQL Clusterは構成できません。

  • 管理ノード・・・・MySQL Cluster内のすべてのノードを管理するノードです。各ノードの起動・停止・バックアップなどを行います。
  • データノード・・・・クラスタのデータを保持するノードです。
  • SQLノード・・・・クラスタのデータにアクセスするためのノードです。SQLノードはNDBストレージエンジンが有効なmysqldのことです。

検証環境

検証環境では2台のサーバーを用意し、それぞれに管理ノード・データノード・SQLノードを起動させます。

また、それぞれを「サーバー1(192.168.1.1)」「サーバー2(192.168.1.2)」とします。各サーバーのOSはCentOS6.5です。

MySQL Clusterインストール

インストールはMySQL本家よりRPMパッケージをダウンロードしてインストールすることにします。

# mysql-libs削除
yum remove mysql-libs

# rpmパッケージのダウンロード
wget http://dev.mysql.com/get/Downloads/MySQL-Cluster-7.3/MySQL-Cluster-gpl-7.3.4-1.el6.x86_64.rpm-bundle.tar
 
# tarアーカイブの展開
tar xvf MySQL-Cluster-gpl-7.3.4-1.el6.x86_64.rpm-bundle.tar
 
# 展開されたrpmパッケージのインストール
rpm -ivh MySQL-Cluster-shared-compat-gpl-7.3.4-1.el6.x86_64.rpm
rpm -ivh MySQL-Cluster-shared-gpl-7.3.4-1.el6.x86_64.rpm
rpm -ivh MySQL-Cluster-devel-gpl-7.3.4-1.el6.x86_64.rpm
rpm -ivh MySQL-Cluster-client-gpl-7.3.4-1.el6.x86_64.rpm
rpm -ivh MySQL-Cluster-server-gpl-7.3.4-1.el6.x86_64.rpm
rpm -ivh MySQL-Cluster-embedded-gpl-7.3.4-1.el6.x86_64.rpm

# 下記エラーが発生したらlibaio入れる
#エラー: 依存性の欠如:
#libaio.so.1()(64bit) は MySQL-Cluster-server-gpl-7.3.4-1.el6.x86_64 に必要とされています
#libaio.so.1(LIBAIO_0.1)(64bit) は MySQL-Cluster-server-gpl-7.3.4-1.el6.x86_64 に必要とされています
#libaio.so.1(LIBAIO_0.4)(64bit) は MySQL-Cluster-server-gpl-7.3.4-1.el6.x86_64 に必要とされています
 
# libaio入れる
yum install libaio
yum install libaio-devel

一応最新のものはこちらから確認するようにしてください。

※ 今回はCentoOSだったので「Red Hat Enterprise Linux / Oracle Linux」でも大丈夫だろうと思いこれにしましたが、もしかしたら「Linux – Generic」のほうが良かったかもしれないです。

ああ4

まあ、結果動いておりますので、これはこれでということで。

設定 〜 起動

my.cnfを編集します。my.cnfはMySQL5.6から「/etc/my.cnf」よりも「/usr/my.cnf」が優先される設定になっていて、インストール時に「/usr/my.cnf」が既に作成されていますので、「/usr/my.cnf」に以下の設定を追加します。

# my.cnf編集
vi /usr/my.cnf

# 下記設定追加
[mysqld]
ndbcluster
ndb-connectstring=192.168.1.1,192.168.1.2

[mysql_cluster]
ndb-connectstring=192.168.1.1,192.168.1.2

mysqldセクションに”ndbcluster”と書いてSQLノードのNDBストレージエンジンを有効化します。また、”ndb-connectstring”で管理ノードを指定しています。
mysql_clusterセクションにはデータノードへの設定を行います。こちらも”ndb-connectstring”で管理ノードを指定しています。

次に管理ノードへ読み込ませる構成情報を記述した設定ファイルを作成します。作成する場所・名前は何でもいいのですが、管理しやすいようにdatadirの中にconfig.iniとして作成します。

vi /var/lib/mysql/config.ini

以下config.iniの内容です。

[ndb_mgmd default]

[ndb_mgmd]
HostName=192.168.1.1

[ndb_mgmd]
HostName=192.168.1.2

[ndbd default]
NoOfReplicas=2
DataDir=/var/lib/mysql-cluster/

[ndbd]
HostName=192.168.1.1

[ndbd]
HostName=192.168.1.2

[mysqld default]

[mysqld]
HostName=192.168.1.1

[mysqld]
HostName=192.168.1.2

基本的にmgmセクションで管理ノードの構成、ndbdセクションでデータノードの構成、mysqldセクションでSQLノードの構成を記述します。
また1つのノードに対して1つのセクションを記載してやる必要があります。例えば今回は各種ノードが2台ありますので、それぞれ2個ずつセクションを記載しています。

また、各ノード種別毎にdefaultとついたセクションが記載できます。これは各ノード種別に複数ノードが存在する場合に共通で使用される構成を記述することができます。このdefaultの構成情報は個々の構成情報より前に記述しなければなりません。
今回の例では全データノードに対して、”NoOfReplicas=2″という構成を設定しています。NoOfReplicasはデータを複製する数を設定します。
そして”DataDir”で各データノードで保持するクラスタデータの保存先を指定しています。一応下記コマンドで、このディレクトリをデータノード上で実行します。

mkdir /var/lib/mysql-cluster
chown mysql:mysql /var/lib/mysql-cluster

設定の最後に各サーバー上で、mysql_secure_installationを実行しておきましょう。mysql_secure_installationはrootのパスワード変更や無名ユーザーの削除等を行ってくれます。

# rootパスワード設定
/usr/bin/mysql_secure_installation
# 既存のrootパスワードを尋ねられるが、インストール後の初期パスワードは「cat ~/.mysql_secret」で確認できる

それでは設定は完了しましたので、まず、それぞれのサーバーで管理ノードを立ち上げます。管理ノードを立ち上げるには以下の様なコマンドを入力します。

ndb_mgmd -f /var/lib/mysql/config.ini
# 出力結果
MySQL Cluster Management Server mysql-5.6.15 ndb-7.3.4
2014-04-18 16:32:22 [MgmtSrvr] WARNING  -- at line 39: Cluster configuration warning:
  arbitrator with id 1 and db node with id 3 on same host 192.168.1.1
  arbitrator with id 2 and db node with id 4 on same host 192.168.1.2
  Running arbitrator on the same host as a database node may
  cause complete cluster shutdown in case of host failure.

ndb_mgmd -f /var/lib/mysql/config.ini
# 出力結果
MySQL Cluster Management Server mysql-5.6.15 ndb-7.3.4
2014-04-18 16:32:16 [MgmtSrvr] WARNING  -- at line 39: Cluster configuration warning:
  arbitrator with id 1 and db node with id 3 on same host 192.168.1.1
  arbitrator with id 2 and db node with id 4 on same host 192.168.1.2
  Running arbitrator on the same host as a database node may
  cause complete cluster shutdown in case of host failure.

管理ノードとデータノードが同じIPだったので、サーバーの障害がクラスタシャットダウンになっちゃうよって言われてますが、今回は気にしません(検証環境ですので)。

ndb_mgmdで管理ノードのデーモンが起動します。-fオプションで、構成情報ファイルを指定しています。

管理ノードにはコンソールがあり、クラスタの状態を確認したりすることができます。管理コンソールを起動するにはndb_mgmと入力します。

ndb_mgm
# 出力結果
-- NDB Cluster -- Management Client --
ndb_mgm>

管理コンソールが起動するとndb_mgm>というコマンドラインが帰ってきます。クラスタの状態を確認するにはSHOWコマンドを入力します。

ndb_mgm> SHOW
Connected to Management Server at: localhost:1186
Cluster Configuration
---------------------
[ndbd(NDB)]	2 node(s)
id=3 (not connected, accepting connect from 192.168.1.1)
id=4 (not connected, accepting connect from 192.168.1.2)

[ndb_mgmd(MGM)]	2 node(s)
id=1	@192.168.1.1  (mysql-5.6.15 ndb-7.3.4)
id=2	@192.168.1.2  (mysql-5.6.15 ndb-7.3.4)

[mysqld(API)]	2 node(s)
id=5 (not connected, accepting connect from 192.168.1.1)
id=6 (not connected, accepting connect from 192.168.1.2)

構成情報ファイルの内容通りに反映されています。現在管理ノードのみ起動している状態なので、管理ノード以外はnot connectedとなっています。

次にデータノードを起動します。各サーバー上で下記コマンドを実行します。

ndbd --nostart
# 出力結果
2014-04-18 16:34:50 [ndbd] INFO     -- Angel connected to 'localhost:1186'
2014-04-18 16:34:50 [ndbd] INFO     -- Angel allocated nodeid: 3

ndbd --nostart
# 出力結果
2014-04-18 16:34:44 [ndbd] INFO     -- Angel connected to 'localhost:1186'
2014-04-18 16:34:44 [ndbd] INFO     -- Angel allocated nodeid: 4

–nostartを指定するとデータノードは待機状態で立ち上がります。待機状態のデータノードは管理コンソール上から起動することができます。

ndb_mgm
# 以下管理コンソール
-- NDB Cluster -- Management Client --
ndb_mgm>3 START # データノード1を起動
Database node 3 is being started.

Node 3: Start initiated (version 7.3.4)

ndb_mgm> SHOW
Cluster Configuration
---------------------
[ndbd(NDB)]	2 node(s)
id=3	@127.0.0.1  (mysql-5.6.15 ndb-7.3.4, starting, Nodegroup: 0) # データノード1が起動中
id=4	@192.168.1.2  (mysql-5.6.15 ndb-7.3.4, not started)

[ndb_mgmd(MGM)]	2 node(s)
id=1	@192.168.1.1  (mysql-5.6.15 ndb-7.3.4)
id=2	@192.168.1.2  (mysql-5.6.15 ndb-7.3.4)

[mysqld(API)]	2 node(s)
id=5 (not connected, accepting connect from 192.168.1.1)
id=6 (not connected, accepting connect from 192.168.1.2)

ndb_mgm> 4 START # データノード1を起動
Database node 4 is being started.

Node 4: Start initiated (version 7.3.4)

ndb_mgm> SHOW
Cluster Configuration
---------------------
[ndbd(NDB)]	2 node(s)
id=3	@127.0.0.1  (mysql-5.6.15 ndb-7.3.4, starting, Nodegroup: 0, *) # データノード1が起動中
id=4	@192.168.1.2  (mysql-5.6.15 ndb-7.3.4, starting, Nodegroup: 0) # データノード2が起動中

[ndb_mgmd(MGM)]	2 node(s)
id=1	@192.168.1.1  (mysql-5.6.15 ndb-7.3.4)
id=2	@192.168.1.2  (mysql-5.6.15 ndb-7.3.4)

[mysqld(API)]	2 node(s)
id=5 (not connected, accepting connect from 192.168.1.1)
id=6 (not connected, accepting connect from 192.168.1.2)

# データノードの起動が完了すると以下の様な表示になります。
ndb_mgm> show
Cluster Configuration
---------------------
[ndbd(NDB)]	2 node(s)
id=3	@127.0.0.1  (mysql-5.6.15 ndb-7.3.4, Nodegroup: 0, *)
id=4	@192.168.1.2  (mysql-5.6.15 ndb-7.3.4, Nodegroup: 0)

[ndb_mgmd(MGM)]	2 node(s)
id=1	@127.0.0.1  (mysql-5.6.15 ndb-7.3.4)
id=2	@192.168.1.2  (mysql-5.6.15 ndb-7.3.4)

[mysqld(API)]	2 node(s)
id=5 (not connected, accepting connect from 192.168.1.1)
id=6 (not connected, accepting connect from 192.168.1.2)

今回はノードのIDを指定して起動しましたが、ALL STARTとすることですべてのデータノードを起動することができます。

最後にSQLノードの起動を行います。SQLノードは通常のmysqlデーモンを起動と同じ手順です。

service mysql start
# 出力結果
Starting MySQL..... SUCCESS! 
ervice mysql start
# 出力結果
Starting MySQL..... SUCCESS! 

SQLノードも管理コンソールから状態が確認できます。

ndb_mgm
# 出力結果
-- NDB Cluster -- Management Client --
ndb_mgm> SHOW
Connected to Management Server at: localhost:1186
Cluster Configuration
---------------------
[ndbd(NDB)]	2 node(s)
id=3	@127.0.0.1  (mysql-5.6.15 ndb-7.3.4, Nodegroup: 0, *)
id=4	@192.168.1.2  (mysql-5.6.15 ndb-7.3.4, Nodegroup: 0)

[ndb_mgmd(MGM)]	2 node(s)
id=1	@192.168.1.1  (mysql-5.6.15 ndb-7.3.4)
id=2	@192.168.1.2  (mysql-5.6.15 ndb-7.3.4)

[mysqld(API)]	2 node(s)
id=5	@192.168.1.1  (mysql-5.6.15 ndb-7.3.4)
id=6	@192.168.1.2  (mysql-5.6.15 ndb-7.3.4)

以上で設定から起動までが完了です。

動作確認

まずサーバー1のSQLノード上で作成したテーブルが、サーバー2のSQLノードから確認できるか試してみます。SQLノード上で通常通りにMySQLコンソールを起動します。

mysql> CREATE DATABASE test;
Query OK, 1 row affected (0.12 sec)

mysql> use test;
Database changed
mysql> CREATE TABLE test (f1 INT) ENGINE ndb;
Query OK, 0 rows affected (0.46 sec)
mysql> USE test;
Database changed
mysql> SHOW TABLES;
+----------------+
| Tables_in_test |
+----------------+
| test           |
+----------------+
1 row in set (0.00 sec)

次はサーバー2上でインサートしたデータがサーバー1上で確認できるか試してみます。

mysql> INSERT INTO test VALUES(1),(2),(3);
Query OK, 3 rows affected (0.02 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> SELECT * FROM test;
+------+
| f1   |
+------+
|    1 |
|    3 |
|    2 |
+------+
3 rows in set (0.01 sec)
mysql> SELECT * FROM test;
+------+
| f1   |
+------+
|    3 |
|    2 |
|    1 |
+------+
3 rows in set (0.00 sec)

データの並び順は逆になっていますが、片側のSQLノードで追加したデータも両方のSQLノードで参照できることが確認できました。

不採用になった理由

うまく動いたのになぜ不採用になったのかというと、大きく2つ理由がありまして。

1つめはオンメモリストレージなので、データの容量がメモリに載りきらなかったということ。ファイルにデータを用意してそこをテーブルスペースにする方法もあるのですが、オンメモリのメリットの速度を犠牲にしてしまうので、それは却下ということに。

もうひとつの理由にJOINの性能が良くないということ。メモリにデータ全部乗らなかったので実測はできていないのですがこれは噂ベースになります。やはり実績やノウハウが少ないものにたいしてはなかなかGOが出ないですね。

結果現段階では、可用性よりも速度重視だぜってことになりました。MySQL Clusterも部分的に導入して速度向上は望めるはずなので、さらなる検証を重ねてまた提案してやるぜ!と。

以上、ただの決意表明でした。

コメントを残す