Hatena::ブログ(Diary)

shibainu55日記

2008-10-26

MySQL Clusterの導入

久しぶりのblog更新。以外にWeb上の記事が少ないこともあって、今回はMySQL Clusterについて触れたいと思う。一通りの機能を解説するのには時間がかかりそうなので、数回に分ける予定。今回はまずは基本的な特徴の紹介と構築手順について。今後は最近機能拡張が行われたディスクベース・クラスタテーブルやバックアップリカバリについても触れていきたい。

MySQL Clusterって?

  • 生い立ち・特徴
    • 実際に使用する場合の構成としては、SQLノードの下図だけ更新系処理の受け口が増えるので、専用アプライアンスLVSなどのL4 ロードバランサの下にぶら下げることで更新系負荷の分散が可能になる。最小構成はRAC同様2台で、この場合には3種類の各ノードを同じ機体に混在させることになる。レプリケーションを使ったマルチマスタ構成の場合には、アプリの設計・実装時から更新系処理の内容やDBの論理設計時に色々な考慮が必要になるが、MySQL Cluster の場合にはクラスタリング対象のデータはデータノードがうまく処理してくれるので、こういった部分についてはアプリ設計では考慮不要なのが嬉しいところ。
  • 開発ロードマップ
    • MySQL 5.1.23からData Nodeの部分が「MySQL Cluster CGE(Carrier Grade Edition) 6.2」として別リリースされ、MySQL Cluster 6.2系として扱うようになった。MySQL 5.1.24からはMySQL Clusterは通常のMySQLには含まれなくなっている(完全に別製品として分離された)。

f:id:shibainu55:20081026222622j:image

  • 3つの構成要素(Node)の役割
    • Data Nodeは、クラスタテーブル(NDBストレージエンジン型で作られたテーブル)の実データを格納するノードである。Node Groupと呼ばれる単位で同一のデータを保持するのが特徴。当初はクラスタテーブルのデータはオンメモリのみであったが、最近はディスクベースでのデータ保持も可能になった(この場合にもインデックスはオンメモリとなる)。ただし、元々オンメモリのみの対応であり、まだディスクベースは苦手な感あり。データノードには大容量の物理メモリの搭載が必須。なおオンメモリのクラスタテーブルのデータが消失しない仕組みは、正常に停止される場合にはディスク上にデータとして格納され、起動時にはこれをメモリ上に再ロードするためである(起動時の動きはHEAPテーブルの使い方に似ている)。

f:id:shibainu55:20081029204042p:image

f:id:shibainu55:20081029204127p:image

    • データ保持・・・デフォルトではオンメモリでデータを格納。全てのデータが同期される。
    • 更新処理・・・ Transaction Coodinaterにクエリが割り当てられ、このノードがデータを保持する複数のノードの全てのデータを確認、更新することでデータの完全性を保証する 。Transaction Coodinaterの役割は、全Data Nodeが持ち回りで担当。Transaction Coodinaterの役割スイッチのトリガは、トランザクションのCOMMITまたはRollBackとなる。
    • 参照処理・・・参照先のデータを保持するData Nodeのうち、Flagment(優先度付け)のあるData Nodeのデータを参照する。

f:id:shibainu55:20081026230448j:image

MySQL Cluster導入手順

MySQL ClusterはManagement Node、SQL Node、Data Nodeの3要素から成り、一般的にはこれらは別のマシンで実行するが、今回は便宜上最小構成での構築とするため、以下のような2台構成で構築を行ってみる。db03にはクラスタ管理ノードSQLノード、データノードの3役、db04はSQLノードとデータノードの2役とし、VMWareで構築。

f:id:shibainu55:20081026211934j:image

ではインストールから。ここでは、RPM版ではなくNON RPM版(tarball版)を使用して構築していきたいと思う。使用する環境はCentOS 4.7 32bit(2.6.9-78.0.1.ELsmp)、MySQL Clusterは6.3.17を採用。一応今回はMySQL製品は何も導入されていないことを前提とする。まずはMySQL Cluster用のOSユーザ・グループを準備。インストール作業は2台のノード両方で行う。

# groupadd  mysql
# useradd -g mysql -d /var/lib/mysql mysql
# passwd mysql

続いて、MySQL Clusterバイナリダウンロードインストールコンパイルなども不要で簡単。今回はSQLノードとしても動作させるためMySQLサーバのデータ保管領域が必要になるが、これはデフォルト(?)のまま/usr/local/mysql/dataとしておく。

# cd /usr/local/src
# wget http://dev.mysql.com/get/Downloads/MySQL-Cluster-6.3/mysql-cluster-gpl-6.3.17-linux-i686-glibc23.tar.gz/from/ftp://mysql.mirror.kangaroot.net/pub/mysql/
# tar -xzf mysql-cluster-gpl-6.3.17-linux-i686-glibc23.tar.gz -C /usr/local/
# cd /usr/local/
# ln -s mysql-cluster-gpl-6.3.17-linux-i686-glibc23/ mysql
# chown -R root.mysql mysql-cluster-gpl-6.3.17-linux-i686-glibc23/
# chown -R mysql.mysql mysql/data/

インストールしたMySQLのbin配下(/usr/local/mysql/bin)にPATHを通しておく。

# cp -p ~/.bash_profile ~/.bash_profile.orig
# vi ~/.bash_profile 
# diff ~/.bash_profile ~/.bash_profile.orig 
10c10
< PATH=$PATH:$HOME/bin:/usr/local/mysql/bin
---
> PATH=$PATH:$HOME/bin
# . ~/.bash_profile 

MySQLの管理DB初期化MySQLの起動スクリプト配備を実施。これでインストールは完了。なんて簡単。

# cd /usr/local/mysql
# ./scripts/mysql_install_db --user=mysql
# cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysql
# chown root.root /etc/init.d/mysql
# chmod u+x /etc/init.d/mysql

続いて、MySQL Clusterを使用するための設定をしていく。まずは管理ノード用の設定から。管理ノードの設定はdb03号機に対してのみ行う。なお、設定ファイルの場所は任意でよい。

# mkdir /var/lib/mysql-cluster
# chown -R mysql.mysql /var/lib/mysql-cluster
# cd /var/lib/mysql-cluster
# vi config.ini

今回は動作するために最低限必要な設定のみの紹介とするため、ほぼカスタマイズなしの構成。注意事項として、設定値にホストを指定する際、設定ファイル内で「ホスト名での記述とIPアドレスでの記述が混在してはならない」という制約がある。ホスト名で指定する場合には、DNS、/etc/hostsなどで確実にリモートホストの名前解決が行えるようにし、設定ファイル内の指定を全てホスト名での記述に統一すること。

[NDB_MGMD]
hostname=192.168.1.113            # Management Node(クラスタ管理ノード)の指定

[NDBD default]
NoOfReplicas=2                    # データを何重に冗長化するかを指定
datadir=/var/lib/mysql-cluster    # MySQL Cluster用データ(NDBテーブル)格納先

[NDBD]
hostname=192.168.1.113            # データノードを指定。ノード数だけ「[NDBD]セクションを記述」

[NDBD]
hostname=192.168.1.114            # データノードを指定

[MYSQLD]
hostname=192.168.1.113            # SQLノードを指定。ノード数だけ「[MYSQLD]セクションを記述」

[MYSQLD]
hostname=192.168.1.114            # SQLノードを指定

次に、db03、db04両サーバに対してSQLノード(MySQLサーバ)の設定を行う。以下のように/etc/my.cnfを設定。ただし、ここでは最低限の設定のみを行っているため、実運用では必要なパラメータを適切に設定する必要があるので注意。ndb_connectstringには、クラスタ管理ノードIPアドレスを指定する。

# cat /etc/my.cnf 
[mysqld]
ndbcluster

[mysql_cluster]
ndb_connectstring=192.168.1.113

[ndb_mgmd]
config_file=/var/lib/mysql-cluster/config.ini

MySQL Clusterの起動

MySQL Clusterの起動は、必ず以下の手順で行う必要がある。停止手順は基本的にはこの逆。

  • 1.Management Nodeの起動
  • 2.Data Nodeの起動
  • 3.SQL Nnodeの起動

では、順に起動していく。まずはdb03号機で管理ノードを起動。起動時にdb03号機上で管理ノードとデータノードが起動している旨の警告が出るが、問題はないのでそのまま無視する。起動前にMySQL Clusterのデータディレクトリに移動しているのは、MySQL ClusterのログがManagement Nodeを起動したディレクトリに出力される仕様であるため、管理上わかりやすくする意味で行っている(なお、管理ノード、データノードの停止方法はプロセスKILL)。

# cd /var/lib/mysql-cluster/
# ndb_mgmd
Warning line 18: Cluster configuration warning:
  arbitrator with id 1 and db node with id 2 on same host 192.168.1.113
  Running arbitrator on the same host as a database node may
  cause complete cluster shutdown in case of host failure.

管理ノードの起動が終わったら、続いてデータノードの起動。データノードはdb03号機、db04号機で起動する。「--initial」オプションをつけることで、以前のMySQL Clusterのログがクリアできる。今回は初回起動だが、念のため付けておく。

# ndbd --initial

正常にデータノードが起動したら、最後にSQLノードを起動する。と言ってもSQLノードは普通のMySQLサーバなので、以下のコマンドで起動するだけ。

# /etc/init.d/mysql start

管理ノード上の管理クライアント(ndb_mgm)を使用してクラスタの状態を確認してみる。

# ndb_mgm
 -- NDB Cluster -- Management Client --
ndb_mgm> show
Connected to Management Server at: 192.168.1.113:1186
Cluster Configuration
 ---------------------
[ndbd(NDB)]     2 node(s)
id=2    @192.168.1.113  (mysql-5.1.27 ndb-6.3.17, Nodegroup: 0, Master)
id=3    @192.168.1.114  (mysql-5.1.27 ndb-6.3.17, Nodegroup: 0)

[ndb_mgmd(MGM)] 1 node(s)
id=1    @192.168.1.113  (mysql-5.1.27 ndb-6.3.17)

[mysqld(API)]   2 node(s)
id=4    @192.168.1.113  (mysql-5.1.27 ndb-6.3.17)
id=5    @192.168.1.114  (mysql-5.1.27 ndb-6.3.17)

では、MySQL Clusterが動作していることを簡単に確認してみる。MySQLクライアントでdb03号機にクラスタテーブルを作ってみよう。クラスタテーブルの作り方もいたって簡単。通常のCREATE TABLE文を使用し、ENGINE句でndbcluster(またはndb)を指定するだけでOK。

# mysql -uroot -D test

mysql> create table t(a int) engine=ndbcluster;
Query OK, 0 rows affected (0.93 sec)

mysql> show table status\G
 *************************** 1. row ***************************
           Name: t
         Engine: ndbcluster
        Version: 10
     Row_format: Fixed
           Rows: 0
 Avg_row_length: 0
    Data_length: 0
Max_data_length: 0
   Index_length: 0
      Data_free: 0
 Auto_increment: NULL
    Create_time: NULL
    Update_time: NULL
     Check_time: NULL
      Collation: latin1_swedish_ci
       Checksum: NULL
 Create_options: 
        Comment: 
1 row in set (0.01 sec)

mysql> insert into t values ('100');
Query OK, 1 row affected (0.01 sec)

mysql> select * from t;
 +------+
 | a    |
 +------+
 |  100 | 
 +------+
1 row in set (0.00 sec)

上記、db03号機で作成したデータが同じクラスタを構成するdb04号機に同期されていることを確認してみる。

# mysql -uroot -D test
mysql> show variables like 'hostname';
 +---------------+-------+
 | Variable_name | Value |
 +---------------+-------+
 | hostname      | db04  | 
 +---------------+-------+
1 row in set (0.00 sec)

mysql> select * from t;
 +------+
 | a    |
 +------+
 |  100 | 
 +------+
1 row in set (0.01 sec)

まったく問題なしですね。これでオンメモリベースのクラスタテーブルを使用できる状態にするところまで、作業が完了。次回以降は、MySQL Clusterのディスクベーステーブルの使い方、バックアップリカバリ、管理クライアントの活用方法などについて説明したいと思います。

はてなユーザーのみコメントできます。はてなへログインもしくは新規登録をおこなってください。

トラックバック - http://d.hatena.ne.jp/shibainu55/20081026/1225011411