---
title: "Keepalived による MariaDB MaxScale の冗長化"
publish_date: 2019-04-02
updated_date: 2023-10-12
author: "MariaDB"
tags:
  - name: "High Availability"
    url: "/ja/resources/blog/tag/high-availability-ja.md"
  - name: "MaxScale"
    url: "/ja/resources/blog/tag/maxscale-ja.md"
---

# Keepalived による MariaDB MaxScale の冗長化

[MariaDB MaxScale](https://staging-mdb.com/kb/en/mariadb-maxscale-23/) は以下のような特長を持つデータベースproxyですが，

- Read/Write Splitter
- SQLファイアウォール
- データマスキング
- 自動フェイルオーバー

反面，MaxScale ノード/インスタンスがダウンした場合に単一障害点(SPOF)になりえます。  
そこで今回は MaxScale を2ノード構成とし，その上位に [Keepalived](http://www.keepalived.org/) を配した構成における MaxScale のフェイルオーバーについて解説致します。

### テスト環境

- CentOS 7.6.1810
- MaxScale 2.3.4 GA
- Keepalived 1.3.5

### Keepalived とは

[Keepalived](http://www.keepalived.org/) は高可用性(HA)/ロードバランシングのためのルーティングツールです。今回は MaxScale を実行している2台のサーバー間で IPフェイルオーバーを設定します。アクティブ MaxScale に障害が発生した場合、スタンバイ MaxScale に仮想IP(VIP)をフェイルオーバーします。  
下図にアーキテクチャを示します。各 MaxScale ノードでは MaxScale と Keepalived を実行し，クライアント/アプリケーションは Keepalived が管理する仮想IP(VIP)に接続します。

![](https://www.s-style.co.jp/blog/wp-content/uploads/2019/03/Keepalived-300x210.png)

各 Keepalived(MaxScale)ノードは常にステータスをブロードキャストし，互いに通信します。片方のノードが他ノードより高い優先順位でステータスメッセージを受信しない場合，そのノードはVIPを要求しマスターになります。

現 MASTERノードが停止した場合，他方のノードは新MASTERとなり，VIPへのトラフィックは新MASTERに向けられ，オリジナルのMASTERノードへの接続は切断されます。再びオリジナルMASTERがオンラインになった場合，再度VIPを要求し、バックアップノードとの接続を切断します。

MaxScale は Keepalived のステータスには関知せず，シングルノード構成と場合と同様にバックエンドDBサーバを監視，クライアント接続を待機します。クライアントはVIPを介して接続しているため，MaxScaleとバックエンドDB間の接続は実IPを使用し，VIPの影響を受けません。

### Keepalived の設定

MaxScale は Keepalived のための特殊な設定を必要としませんが，双方のノードで実行されている必要があり，MaxScale の設定は同様に設定する必要があります。MaxScale の service 設定では，クライアントがどちらの MaxScale ノードに接続したかを明確にするために `version_string` をノード毎に異なる値に設定することを推奨いたします。

###### プライマリ MaxScale ノードの R/Wスプリッター serviceの設定例

```
[Read-Write-Split-Service]
type=service
router=readwritesplit
version_string=PrimaryMaxScale

```

Keepalived は双方のノードで priority を異なる値に設定する必要があります。プライマリ・ノードでは /etc/keepalived/keepalived.conf を次のように設定します(priority 150)。

```
vrrp_instance VI_1 {
  state MASTER
  interface eth1
  virtual_router_id 51
  priority 150
  advert_int 1
  authentication {
    auth_type PASS
    auth_pass mypass
  }
  virtual_ipaddress {
    192.168.2.230
  }
}

```

ここで，

- state : 双方のノードで MASTER
- virtual\_router\_id と auth\_pass は同一
- interface : 使用されるネットワークインタフェース
- priority : どちらがMASTERになるべきかを決定するための優先度。ここではプライマリ・ノードを150にする
- advert\_int : 他のKeepalived ノードに自分の存在を”アドバタイズ”する時間間隔。ここでは1秒
- virtual\_ipaddress(VIP) は Keepalived ノードが利用しようとする仮想IPアドレス。VIPが同一LAN内にあり、LAN内の他ホストが利用していないIPアドレスである必要があります。

セカンダリ・ノード用の keepalived.conf の例を以下に示します(priority 100)。

```
vrrp_instance VI_1 {
  state MASTER
  interface eth1
  virtual_router_id 51
  priority 100
  advert_int 1
  authentication {
    auth_type PASS
    auth_pass mypass
  }
  virtual_ipaddress {
    192.168.2.230
  }
}

```

### MaxScale のヘルスチェック(死活監視)

MaxScale が Keepalived MASTERノードで稼働中であることを確認するには，ヘルスチェック・スクリプトを定期的に実行する必要があります。ヘルスチェック・スクリプトがエラーを返すと，ステータス・ブロードキャストを停止し，VIPを放棄します。  
これにより他ノードが MASTERステータスを取得し，VIPを割り当てることができます。  
例えばプライマリ・ノードでは次のように設定します。

参考: [Keepalived Check and Notify Scripts](https://tobru.ch/keepalived-check-and-notify-scripts/)

```
vrrp_script chk_myscript {
  script "/home/vagrant/is_maxscale_running.sh"
  interval 5 # check every 5 seconds
  fall 2 # require 2 failures for KO
  rise 2 # require 2 successes for OK
}

vrrp_instance VI_1 {
  state MASTER
  interface eth1
  virtual_router_id 51
  priority 150
  advert_int 1
  authentication {
    auth_type PASS
    auth_pass mypass
  }
  virtual_ipaddress {
    192.168.2.230
  }
  track_script {
    chk_myscript
  }
}

```

is\_maxscale\_running.sh の例:

```
#!/bin/bash
fileName="maxctrl_output.txt"
rm $fileName
timeout 5s maxctrl list servers > $fileName
to_result=$?
if [ $to_result -ge 1 ]
then
  echo Timed out or error, timeout returned $to_result
  exit 3
else
  echo maxctrl success, rval is $to_result
  echo Checking maxctrl output sanity
  grep1=$(grep server1 $fileName)
  grep2=$(grep server2 $fileName)

  if [ "$grep1" ] && [ "$grep2" ]
  then
    echo All is fine
    exit 0
  else
    echo Something is wrong
    exit 3
  fi
fi

```

### MaxScale active/passive設定

MaxScale を複数稼働させていて，なおかつ MariaDB Monitor(mariadbmon) の [auto\_failover](https://staging-mdb.com/kb/en/mariadb-maxscale-23-mariadb-monitor/#auto_failover) / [auto\_rejoin](https://staging-mdb.com/kb/en/mariadb-maxscale-23-mariadb-monitor/#auto_rejoin) を有効にしている場合，MaxScale 間でMariaDB Monitor が競合しますので，BACKUPノードでは auto\_failover / auto\_rejoin を無効にする必要があり，グローバル設定の passive パラメータで制御することができます。

MASTER(Active) ノードでは，

```
maxctrl alter maxscale passive false

```

により，passive=false (active) に設定，反対に BACKUP(Standby) ノードでは，

```
maxctrl alter maxscale passive true

```

により，passive=true に設定します。  
passive=true になると，auto\_failover=false / auto\_rejoin=false となり，自動 failover / rejoin を行いません。

### MaxScale のフェイルオーバーテスト

プライマリ・ノードを reboot ，再起動中に MaxScale がセカンダリに自動 フェイルオーバーするかテストしてみます。

セカンダリ・ノードの /var/log/messages:

```
Mar 13 20:37:43 mxs2 Keepalived_vrrp[8390]: VRRP_Instance(VI_1) Transition to MASTER STATE
Mar 13 20:37:44 mxs2 Keepalived_vrrp[8390]: VRRP_Instance(VI_1) Entering MASTER STATE
Mar 13 20:37:44 mxs2 Keepalived_vrrp[8390]: VRRP_Instance(VI_1) setting protocol VIPs.
Mar 13 20:37:44 mxs2 Keepalived_vrrp[8390]: Sending gratuitous ARP on eth1 for 192.168.2.230
Mar 13 20:37:44 mxs2 Keepalived_vrrp[8390]: VRRP_Instance(VI_1) Sending/queueing gratuitous ARPs on eth1 for 192.168.2.230
Mar 13 20:37:44 mxs2 Keepalived_vrrp[8390]: Sending gratuitous ARP on eth1 for 192.168.2.230
Mar 13 20:37:44 mxs2 Keepalived_vrrp[8390]: Sending gratuitous ARP on eth1 for 192.168.2.230
Mar 13 20:37:44 mxs2 Keepalived_vrrp[8390]: Sending gratuitous ARP on eth1 for 192.168.2.230
Mar 13 20:37:44 mxs2 Keepalived_vrrp[8390]: Sending gratuitous ARP on eth1 for 192.168.2.230
Mar 13 20:37:49 mxs2 Keepalived_vrrp[8390]: Sending gratuitous ARP on eth1 for 192.168.2.230
Mar 13 20:37:49 mxs2 Keepalived_vrrp[8390]: VRRP_Instance(VI_1) Sending/queueing gratuitous ARPs on eth1 for 192.168.2.230
Mar 13 20:37:49 mxs2 Keepalived_vrrp[8390]: Sending gratuitous ARP on eth1 for 192.168.2.230
Mar 13 20:37:49 mxs2 Keepalived_vrrp[8390]: Sending gratuitous ARP on eth1 for 192.168.2.230
Mar 13 20:37:49 mxs2 Keepalived_vrrp[8390]: Sending gratuitous ARP on eth1 for 192.168.2.230
Mar 13 20:37:49 mxs2 Keepalived_vrrp[8390]: Sending gratuitous ARP on eth1 for 192.168.2.230
Mar 13 20:38:01 mxs2 Keepalived_vrrp[8390]: VRRP_Instance(VI_1) Received advert with higher priority 150, ours 100
Mar 13 20:38:01 mxs2 Keepalived_vrrp[8390]: VRRP_Instance(VI_1) Entering BACKUP STATE
Mar 13 20:38:01 mxs2 Keepalived_vrrp[8390]: VRRP_Instance(VI_1) removing protocol VIPs.

```

プライマリ・ノードがシャットダウンされた直後にセカンダリ・ノードが MASTER STATE に移行し，プライマリ・ノードの reboot が完了すると，セカンダリ・ノードが再び BACKUP STATE になっていることが確認できます。

### まとめ

今回は SPOF を回避するために MaxScale を複数稼働させ，Keepalived を用いて片方の MaxScale がダウンした場合に高速自動フェイルオーバーする MaxScale の高可用構成について解説いたしました。DNS設定などでフェイルオーバーするロードバランサーなどと比較してより高速に切り替わることが確認できました。

参考 Knowledge Base ページ: [MaxScale 2.3 Failover with Keepalived and MaxCtrl](https://staging-mdb.com/kb/en/mariadb-maxscale-23-maxscale-failover-with-keepalived-and-maxctrl/)