CentOS7 + MySQL Cluster 7.4.7 検証メモ



俗にいうNDB ClusterのVagrantでの構築試験メモ。
本書では特に断りなく、「MySQL Cluster」のことを「NDB Cluster」と記載することとする。

# はじめに

本検証は[過去のPercona XtraDB Cluster検証](http://qiita.com/Ets/items/1fd77c1cb714d04d3dfa#vagrant-セットアップ)の後で行った検証メモになっているので、説明不足な部分があるかも知れない。

## これから作るもの

オンメモリの高速MySQLサーバーエンジンのMySQL Cluster、俗にいうNDB Clusterである。
本来は以下の役割毎に分けて複数台構成するべきなのだが、ノード2台構成で構築して、「とにかく試す」ということを目的としている。

* 管理ノード
* SQLノード
* データノード 


## 手順について

本手順ではコンソール作業を「$」プロンプトで書いているけれど、 **全部root作業** だと思ってほしい。フォーマットの関係で#だとコメントアウトになってしまって読みにくいので・・・

## 事前作業

Vagrantの環境を整える。
以下は基本的に[過去のPercona XtraDB Cluster検証手順](http://qiita.com/Ets/items/1fd77c1cb714d04d3dfa#vagrant-セットアップ)と同じなのだが、共存できるようにホスト名やIPアドレスを変更しているので、記録しておく。


## 試験環境の構築

とにもかくにもVagrantが楽ちんなのでVagrantで作る。

### Vagrant セットアップ

```bash
$ vagrant box add centos7 https://github.com/holms/vagrant-centos7-box/releases/download/7.1.1503.001/CentOS-7.1.1503-x86_64-netboot.box
$ vagrant init centos7

$ vim VagrantFile
```

最後のendの前に、以下を追加する。
設定値中のメモリサイズとかは各環境で調整してほしい。

```Vagrantfile
  ### server3の設定内容
  config.vm.define "s3" do |server|
    server.vm.hostname = config.vm.box + "-s3" + ".vagrant"
    server.vm.network "private_network", ip: "192.168.200.103", host: "52003"
    config.vm.provider "virtualbox" do |vb|
      ### virtualbox上で表示される名前
      vb.name = config.vm.box + "_s3"
      vb.customize ["modifyvm", :id, "--memory", "2048"]
      vb.customize ["modifyvm", :id, "--cpus", "2"]
    end
  end
  ### server4の設定内容
  config.vm.define "s4" do |server|
    server.vm.hostname = config.vm.box + "-s4" + ".vagrant"
    server.vm.network "private_network", ip: "192.168.200.104", host: "52004"
    config.vm.provider "virtualbox" do |vb|
      ### virtualbox上で表示される名前
      vb.name = config.vm.box + "_s4"
      vb.customize ["modifyvm", :id, "--memory", "2048"]
      vb.customize ["modifyvm", :id, "--cpus", "1"]
    end
  end
```

起動

```bash
$ vagrant up s3
$ vagrant up s4
```

以降はこんな感じでログインできる。(vagrant ssh使ってもいいけど)

```bash
$ ssh 192.168.200.103 -l root
$ ssh 192.168.200.104 -l root

どちらも、パスワードはvagrant
```

疎通NGのときは`vagrant reload s3`してみよう。

・・・ここまで前の手順のコピーと置換。


# NDB Cluster インストール

## パッケージインストール

ここからダウンロードする。
https://dev.mysql.com/downloads/cluster/

結構大きいサイズなので、/vagrantで作業すると共有できて便利。

```bash
$ cd /vagrant
$ wget https://dev.mysql.com/get/Downloads/MySQL-Cluster-7.4/MySQL-Cluster-gpl-7.4.7-1.el7.x86_64.rpm-bundle.tar
```

展開すると、こんな感じのRPMが出てくる。

```
$ tar xvf MySQL-Cluster-gpl-7.4.7-1.el7.x86_64.rpm-bundle.tar
MySQL-Cluster-shared-compat-gpl-7.4.7-1.el7.x86_64.rpm
MySQL-Cluster-devel-gpl-7.4.7-1.el7.x86_64.rpm
MySQL-Cluster-server-gpl-7.4.7-1.el7.x86_64.rpm
MySQL-Cluster-embedded-gpl-7.4.7-1.el7.x86_64.rpm
MySQL-Cluster-shared-gpl-7.4.7-1.el7.x86_64.rpm
MySQL-Cluster-test-gpl-7.4.7-1.el7.x86_64.rpm
MySQL-Cluster-client-gpl-7.4.7-1.el7.x86_64.rpm
```

前提パッケージを入れる。

```
$ yum install -y net-tools
$ yum install -y perl-Data-Dumper
$ rpm -ivh MySQL-Cluster-client-gpl-7.4.7-1.el7.x86_64.rpm
```

ver6.Xと違い、SQLノードもデータノードも管理ノードも、このRPMでOK。

```
$ rpm -ivh MySQL-Cluster-server-gpl-7.4.7-1.el7.x86_64.rpm
```


## 初期設定

RPMでインストールを終えると、なぜかわからないが`/usr/my.cnf`に設定ファイルのひな形が置かれている。しかも、そのファイルには大した情報が書かれていないので、ベースに使っても楽にはならない。

以下のように設定を作っていこう。

### 共通

もちろん設計には依るのだが、私は関連ファイルの格納パスとして以下を作成した。

```bash
$ mkdir -p /var/lib/mysql-cluster/data
$ mkdir -p /var/lib/mysql-cluster/log
```

### 管理ノード・データノードの設定

引き続き、管理ノード・データノードの設定を作る。

```bash
$ mkdir /var/lib/mysql-cluster
$ vi /var/lib/mysql-cluster/config.ini
```

中身。`DataMemory`サイズやIPアドレス部分は環境によって調整が必要だろう。最初に作成したディレクトリを、各セクションの`datadir`変数で使用している。

nodeidは1〜48から選ぶ必要がある。
ノードの役割が違っていても、クラスター内で重複していてはいけない。

```/var/lib/mysql-cluster/config.ini
[ndbd default]
# Options affecting ndbd processes on all data nodes:
NoOfReplicas=2    # Number of replicas
DataMemory=200M    # How much memory to allocate for data storage
IndexMemory=18M   # How much memory to allocate for index storage
                  # For DataMemory and IndexMemory, we have used the
                  # default values. Since the "world" database takes up
                  # only about 500KB, this should be more than enough for
                  # this example Cluster setup.

[tcp default]
# TCP/IP options:
portnumber=2202   # This the default; however, you can use any
                  # port that is free for all the hosts in the cluster
                  # Note: It is recommended that you do not specify the port
                  # number at all and simply allow the default value to be used
                  # instead

[ndb_mgmd]
nodeid=48
# Management process options:
hostname=192.168.200.103        # Hostname or IP address of MGM node
datadir=/var/lib/mysql-cluster/log  # Directory for MGM node log files

[ndbd]
nodeid=11
hostname=192.168.200.103        # Hostname or IP address
datadir=/var/lib/mysql-cluster/data   # Directory for this data node's data files

[ndbd]
nodeid=12
hostname=192.168.200.104        # Hostname or IP address
datadir=/var/lib/mysql-cluster/data   # Directory for this data node's data files

[mysqld]
nodeid=1
hostname=192.168.200.103        # Hostname or IP address

[mysqld]
nodeid=2
hostname=192.168.200.104        # Hostname or IP address
```

これを全ノードに配る。

### SQLノードの設定

[オフィシャルのマニュアル](http://dev.mysql.com/doc/refman/5.6/en/mysql-cluster-install-configuration.html)に沿って、このように`/etc/my.cnf`ファイルを作る。

```/etc/my.cnf
[mysqld]
user = mysql
datadir = /var/lib/mysql
log_bin
default_storage_engine  = InnoDB

# In order for Galera to work correctly binlog format should be ROW
binlog_format                  = ROW
log-bin=/var/lib/mysql/mysqld-bin
expire_logs_days=1

innodb_buffer_pool_size        = 100M
innodb_flush_log_at_trx_commit = 0
innodb_flush_method            = O_DIRECT
innodb_log_files_in_group      = 2
innodb_log_file_size           = 64M
innodb_file_per_table          = 1
innodb_locks_unsafe_for_binlog = 1
innodb_autoinc_lock_mode       = 2

explicit_defaults_for_timestamp = 0

# Cluster
server_id = 3
ndbcluster                      # run NDB storage engine


!includedir /etc/my.cnf.d

[mysqld_safe]
pid-file = /run/mysqld/mysql.pid
syslog


[mysql_cluster]
# Options for MySQL Cluster processes:
ndb-connectstring=192.168.200.103  # location of management server
```

重要なのは`ndbcluster`設定値と`[mysql_cluster]`セクション。
これをクラスターに参加する全ノードにserver_idを変えて配る。


# 初回起動


## 管理ノード起動


管理ノードを起動する。この例ではノード1で起動する。
起動すると、管理ノードとデータノードを同じホスト(IPアドレス)で動かそうとしてるので警告されるが、起動そのものは成功する。

```bash
# ndb_mgmd -f /var/lib/mysql-cluster/config.ini
MySQL Cluster Management Server mysql-5.6.25 ndb-7.4.7
2015-08-28 10:18:17 [MgmtSrvr] WARNING  -- at line 41: Cluster configuration warning:
  arbitrator with id 48 and db node with id 11 on same host 192.168.200.103
  Running arbitrator on the same host as a database node may
  cause complete cluster shutdown in case of host failure.
```

## データノード起動

データノード1を起動する。

```
$ ndbd
2015-08-28 10:33:37 [ndbd] INFO     -- Angel connected to '192.168.200.103:1186'
2015-08-28 10:33:37 [ndbd] INFO     -- Angel allocated nodeid: 11
```

この時エラーが出るようなら、ファイアウォール(firewall-cmd)周りが疑わしい。

データノード2を起動する。

```
$ ndbd
2015-08-28 10:34:39 [ndbd] INFO     -- Angel connected to '192.168.200.103:1186'
2015-08-28 10:34:39 [ndbd] INFO     -- Angel allocated nodeid: 12
```

あっさり参加できる。

ノード1(管理ノード)で確認してみる。

```bash
$ ndb_mgm
-- NDB Cluster -- Management Client --
ndb_mgm> show
Connected to Management Server at: 192.168.200.103:1186
Cluster Configuration
---------------------
[ndbd(NDB)]	2 node(s)
id=11	@192.168.200.103  (mysql-5.6.25 ndb-7.4.7, Nodegroup: 0, *)
id=12	@192.168.200.104  (mysql-5.6.25 ndb-7.4.7, Nodegroup: 0)

[ndb_mgmd(MGM)]	1 node(s)
id=48	@192.168.200.103  (mysql-5.6.25 ndb-7.4.7)

[mysqld(API)]	2 node(s)
id=1 (not connected, accepting connect from 192.168.200.103)
id=2 (not connected, accepting connect from 192.168.200.104)
```

## SQLノード起動

それぞれのホストで、SQLノードも起動しよう。

```bash
$ mysql_install_db --datadir=/var/lib/mysql --user=mysql
$ systemctl start mysql
```

ndb_mgmコマンドで確認する。

```bash
$ ndb_mgm
-- NDB Cluster -- Management Client --
ndb_mgm> show
Connected to Management Server at: 192.168.200.103:1186
Cluster Configuration
---------------------
[ndbd(NDB)]	2 node(s)
id=11	@192.168.200.103  (mysql-5.6.25 ndb-7.4.7, Nodegroup: 0, *)
id=12	@192.168.200.104  (mysql-5.6.25 ndb-7.4.7, Nodegroup: 0)

[ndb_mgmd(MGM)]	1 node(s)
id=48	@192.168.200.103  (mysql-5.6.25 ndb-7.4.7)

[mysqld(API)]	2 node(s)
id=1	@192.168.200.103  (mysql-5.6.25 ndb-7.4.7)
id=2	@192.168.200.104  (mysql-5.6.25 ndb-7.4.7)
```

それぞれのノードが認識されている。

# 動作試験

## 準備
mysqlslap用試験設定を書いて負荷をかけてみる。
試験用のこんなファイルを用意する。（オプションが多いのでファイルにしておく）

```/vagrant/mysqlslap.sh
mysqlslap \
  --no-defaults \
  --concurrency=5 \
  --iterations=4 \
  --engine=ndb \
  --auto-generate-sql \
  --auto-generate-sql-add-autoincrement \
  --auto-generate-sql-load-type=mixed \
  --auto-generate-sql-write-number=1000 \
  --number-of-queries=100000 \
  --host=localhost \
  --port=3306 \
  --user=root \
  -vv
```

## 実行

```bash
$ bash /vagrant/mysqlslap.sh
Building Create Statements for Auto
Building Query Statements for Auto
Parsing engines to use.
Starting Concurrency Test
Loading Pre-data
Generating primary key list
Loading Pre-data
Generating primary key list
Loading Pre-data
Generating primary key list
Loading Pre-data
Generating primary key list
Generating stats
Benchmark
	Running for engine ndb
	Average number of seconds to run all queries: 58.662 seconds
	Minimum number of seconds to run all queries: 57.661 seconds
	Maximum number of seconds to run all queries: 59.899 seconds
	Number of clients running queries: 5
	Average number of queries per client: 20000
```

すげー遅い！

topを見ていると、mysqldとndbdが互いにリソースを食い合っているようだ。
明らかなパフォーマンス不足。CPU不足、メモリ不足、ノード不足。
ちゃんとした構成をとらないとなぁ。