Galera Cluster(10.1) + MaxScale(2.4)で自動フェイルオーバーとデッドロック解消

#Galera ClusterにMaxScaleを導入

本記事では、**MariaDBのGalera ClusterにMaxScaleを導入する手順**について紹介していきたいと思います。

前回は、CentOS7にGalera Clusterを構築しました。
https://qiita.com/rui-watanabe/items/3d0193f8fcfefa8902ba

ただGalera Clusterはそれぞれのノードで読み込み・可能であるため、**デッドロックが起こる可能性**があります。

その**デッドロックを解消し、自動フェイルオーバー**を可能とするのが、今回紹介するMaxScaleです。

#前提条件
- MaxScale用のCentOS7のサーバー(プライベートIP:192.168.0.1)
- Galera Clusterノード3台(プライベートIP:192.168.0.2、192.168.0.3、192.168.0.4)をローカルネットワーク内で構築済み


#デッドロックとは？
複数のユーザー（複数のノード）が同じタイミングで、同じデータベースの行にデータの更新をしようとした場合、デッドロックが起こります。

そもそもデッドロックとは、**処理が競合してしまいデータの更新ができない状態**で、トランザクションを利用した更新によく起こる現象です。

これでは、複数の処理をまとめて処理するトランザションでデッドロックが起こる例を挙げていきます。

ユーザーXとユーザYがいて、それぞれデータAとデータBを書き換えようとしたとします。

ユーザーXはデータAを書き換えることで、ロックを取得します。

ロックを取得すると、他のユーザーはデータを書き換えられない状況となります。

同じようにユーザーYは、データBを書き換えることでロックを取得します。

同じタイミングでユーザーXがデータBを書き換えて更新し、ユーザーYはデータAを書き換えて更新しようとします。

ここで他ユーザーのロック取得により、**ユーザーX、ユーザーY共にデータを更新ができなくなる状況に**。

これが、デッドロックです。

このデッドロックは、**複数ノードで読み込み・書き込み可能なGalera Cluster**で起こる可能性があります。

#マスター・スレーブ型レプリケーションにすればデッドロック解決？

ただこのデッドロックは、以前書いた下記記事の**マスター・スレーブ型レプリケーション**にすれば解決できるのではないかと思いました。
https://qiita.com/rui-watanabe/items/4f2ba392df5b894eb587

マスター・スレーブ型レプリケーションでは、マスターが更新・読み込み処理をしてスレーブが読み込み処理をしてくれます。

しかし、マスター・スレーブ型レプリケーションではまた別の問題点がありました。

マスターサーバーに負荷が集中して落ちてしまうと、**更新処理ができなくなってしまう**のです。

#MaxScaleでデッドロック解消・自動フェイルオーバー

そのマスターサーバーが落ち更新処理ができない問題と、デッドロックを解消するのがMaxScaleです。

Galera Cluster　+ MaxScaleでは、マスター・スレーブ型レプリケーションのように、**1台のノードをマスターノード（書き込み処理のクエリ担当）**とし、**他のノードをスレーブノード（読み込み処理のクエリ担当）**とします。

そのため複数のユーザーが同時に更新処理をしても、更新はマスターノードのみが処理するのでデッドロックを解消してくれます。

また、MaxScaleはクラスターをモニタリングできる機能があるので、マスターサーバーが落ちてしまったら他のノードがマスターサーバーに昇格する**自動フェイルオーバー**で、更新処理ができなくなる問題も解決します。

さらにそれぞれのスレーブノードでは、**負荷が少ないノードで処理をしてくれる負荷分散も可能に**できます。

#MaxScaleの導入手順

ここから、MaxScaleの導入手順を記載していきます。

## ノード1でMaxScale用ユーザー作成

MaxScale設定の前に、あらかじめノード1で初期ノードを立ち上げ、MaxScale用ユーザーを作成します。

1ノードでユーザーを作成すれば、他のノードでも反映されます。

```
# galera_new_cluster

# mysql -u root -p

MariaDB [(none)]> GRANT ALL ON *.* to 'maxadmin'@'%';
```


## MaxScaleインストール

MaxScale用CentOS7のサーバーにMaxScaleをインストールします。

まず、MariaDB関連のリポジトリーを設定。

```
# curl -sS https://downloads.mariadb.com/MariaDB/mariadb_repo_setup | sudo bash
```

その後、MaxScaleをインストール。

```
# yum -y install maxscale
```

## MaxScale設定

次に、/etc/maxscale.cnfにMaxScale設定をしていきます。

maxscale.cnfに、Galera ClusterのMaxScale設定を書き加えます。

Galera Cluster+ MaxScaleでは、マスターノードを更新系クエリに、スレーブノードを

```
# vi /etc/maxscale.cnf

[maxscale]
threads=auto

[galera1]
type=server
address=192.168.0.2　
port=3306
protocol=MariaDBBackend

[galera2]
type=server
address=192.168.0.3
port=3306
protocol=MariaDBBackend

[galera3]
type=server
address=192.168.0.4
port=3306
protocol=MariaDBBackend

############################################################################


[Galera-Monitor]
type=monitor
module=galeramon
servers=galera1,galera2,galera3
user=maxadmin
password=maxpwd
monitor_interval=2000

############################################################################

# ルーターはマスター・スレーブごとに読み込み書き込みを分ける、readwritesplitを指定
[Splitter-Service]
type=service
router=readwritesplit
servers=galera1,galera2,galera3
user=maxadmin
password=maxpwd

############################################################################

# Splitterのポートはデフォルトの4006を使用
[Splitter-Listener]
type=listener
service=Splitter-Service
protocol=mariadbclient
port=4006
```

MaxScaleサーバーと各ノードのfirewallで、ポート4006を許可します。

```
# firewall-cmd --add-port=4006 --permanent
# firewall-cmd --reload
```

## MaxScale起動と確認

MaxScaleを起動し、初期ノード(192.168.0.2)がMasterになっているか確認。

```
# systemctl start maxscale

# maxctrl list servers
┌─────────┬──────────────┬──────┬─────────────┬─────────────────────────┬──────┐
│ Server  │ Address      │ Port │ Connections │ State                   │ GTID │
├─────────┼──────────────┼──────┼─────────────┼─────────────────────────┼──────┤
│ galera1 │ 192.168.0.2  │ 3306 │ 0           │ Master, Synced, Running │      │
├─────────┼──────────────┼──────┼─────────────┼─────────────────────────┼──────┤
│ galera2 │ 192.168.0.3  │ 3306 │ 0           │ Down                    │      │
├─────────┼──────────────┼──────┼─────────────┼─────────────────────────┼──────┤
│ galera3 │ 192.168.0.4  │ 3306 │ 0           │ Down                    │      │
└─────────┴──────────────┴──────┴─────────────┴─────────────────────────┴──────┘
```

2台目(192.168.0.3)、３台目(192.168.0.4)のノードを立ち上げて、スレーブになっているか確認。

```
# systemctl start mariadb　//２台目、３台目のノード
```
```
# maxctrl list servers
┌─────────┬──────────────┬──────┬─────────────┬─────────────────────────┬──────┐
│ Server  │ Address      │ Port │ Connections │ State                   │ GTID │
├─────────┼──────────────┼──────┼─────────────┼─────────────────────────┼──────┤
│ galera1 │ 192.168.0.2  │ 3306 │ 0           │ Master, Synced, Running │      │
├─────────┼──────────────┼──────┼─────────────┼─────────────────────────┼──────┤
│ galera2 │ 192.168.0.3  │ 3306 │ 0           │ Slave, Synced, Running  |      |
├─────────┼──────────────┼──────┼─────────────┼─────────────────────────┼──────┤
│ galera3 │ 192.168.0.4  │ 3306 │ 0           │ Slave, Synced, Running  |      |
└─────────┴──────────────┴──────┴─────────────┴─────────────────────────┴──────┘
```

Service,Router,Serversが設定されているかを確認。

```
# maxctrl list services
┌──────────────────┬────────────────┬─────────────┬──────────────────────────┐
│ Service          │ Router         │ Connections │ Servers                  │
├──────────────────┼────────────────┼─────────────┼──────────────────────────┤
│ Splitter-Service │ readwritesplit │ 0           │ galera1,galera2,galera3  │
└──────────────────┴────────────────┴─────────────┴──────────────────────────┘
```


Masterノードが落ちた時に、2つ目のSlaveノードがMasterに変わるかの、フェイルオーバーの検証。


```
# reboot　//1台目のノード
```
```
# maxctrl list servers
┌─────────┬──────────────┬──────┬─────────────┬─────────────────────────┬──────┐
│ Server  │ Address      │ Port │ Connections │ State                   │ GTID │
├─────────┼──────────────┼──────┼─────────────┼─────────────────────────┼──────┤
│ galera1 │ 192.168.0.2  │ 3306 │ 0           │ Down                    │      │
├─────────┼──────────────┼──────┼─────────────┼─────────────────────────┼──────┤
│ galera2 │ 192.168.0.3  │ 3306 │ 0           │ Master, Synced, Running │      │
├─────────┼──────────────┼──────┼─────────────┼─────────────────────────┼──────┤
│ galera3 │ 192.168.0.4  │ 3306 │ 0           │ Slave, Synced, Running  │      │
└─────────┴──────────────┴──────┴─────────────┴─────────────────────────┴──────┘
```

1台目のノードが再度立ち上がるとSlaveになり、2台目のノードがMasterになります。

```
# maxctrl list servers
┌─────────┬──────────────┬──────┬─────────────┬─────────────────────────┬──────┐
│ Server  │ Address      │ Port │ Connections │ State                   │ GTID │
├─────────┼──────────────┼──────┼─────────────┼─────────────────────────┼──────┤
│ galera1 │ 192.168.0.2  │ 3306 │ 0           │ Slave, Synced, Running  │      │
├─────────┼──────────────┼──────┼─────────────┼─────────────────────────┼──────┤
│ galera2 │ 192.168.0.3  │ 3306 │ 0           │ Master, Synced, Running |      |
├─────────┼──────────────┼──────┼─────────────┼─────────────────────────┼──────┤
│ galera3 │ 192.168.0.4  │ 3306 │ 0           │ Slave, Synced, Running  |      |
└─────────┴──────────────┴──────┴─────────────┴─────────────────────────┴──────┘
```

これでGalera ClusterにMaxScaleを導入することが完了しました。


#参考記事
https://mariadb.com/kb/en/mariadb-maxscale-24-mariadb-maxscale-configuration-guide/#listener
https://oss-db.jp/dojo/dojo_12
http://cream-worker.blog.jp/archives/1072469111.html
https://qiita.com/cherubim1111/items/617e73355cf74c485936
https://www.designet.co.jp/faq/term/?id=TWFyaWFEQiBNYXhTY2FsZQ
https://www.designet.co.jp/ossinfo/mariadb/