HAProxyを使ってMySQLの負荷分散をする時はmysql-checkのuserオプションを使う

記事タイトルとURLをコピーする
こんにちは、テクニカルグループの柳瀬です。 アプリケーションサーバからMySQLへの参照を負荷分散する場合、HAProxyを使うことがあります。 AWS上で構築している場合はリードレプリカへの参照を負荷分散させたいというご要望を受けた時ですね。 HAProxyは負荷分散対象に監視を設定し、ダウンと判断したものは分散対象から除外してくれるのでとても便利です。 しかし、MySQLへTCPで監視を設定しているとMySQL側が監視用のパケットを不正と判断して、リクエストを受け付けなくなってしまいます。 max_connect_errorsを大きい値にするという対応もありますが、HAProxyの監視設定で使用するmysql-checkにユーザーオプションを使用すれば不正なパケットとはなりません。

検証環境構成

  • Amazon Linux
  • HAProxy 1.4.22
  • RDS(Multi AZ)
  • RDSリードレプリカ×2

MySQLクライアントのインストール

まずはこれをインストールしないとはじまりませんよね。
$ sudo yum install mysql

HAProxy用のログ設定

きちんとログを出力するように設定しておきます。
$ sudo vi /etc/rsyslog.conf
$ModLoad imudp
$UDPServerRun 514
# haproxy setting
local2.*                                                /var/log/haproxy.log
$ sudo service rsyslog restart

HAProxyの監視用ユーザーを作成

マスターのDBに接続してユーザーを作成します。
$ mysql -u okochang -p -h yanase.chmbfm8ojccp.ap-northeast-1.rds.amazonaws.com
mysql> grant usage on *.* to 'haproxy'@'%';
$ mysqladmin ping -u haproxy -h yanase.chmbfm8ojccp.ap-northeast-1.rds.amazonaws.com
mysqld is alive

HAProxyのインストールと設定

option mysql-checkの後にuser haproxyと記載されているところがポイントです。 以下の設定ではリードレプリカがダウンした場合はMasterとなるRDSに接続するようになっています。
$ sudo yum install haproxy
$ sudo vi /etc/haproxy/haproxy.cfg
global
    log 127.0.0.1 local2
    chroot /var/lib/haproxy
    pidfile /var/run/haproxy.pid
    maxconn 4000
    user haproxy
    group haproxy
    daemon
    stats socket /var/lib/haproxy/stats
defaults
    mode tcp
    log global
    retries 3
    timeout connect 10s
    timeout client 1m
    timeout server 1m
    timeout check 10s
    maxconn 3000
listen mysql
    bind 0.0.0.0:3306
    mode tcp
    option mysql-check user haproxy
    balance roundrobin
    server read1 yanase-rr01.chmbfm8ojccp.ap-northeast-1.rds.amazonaws.com:3306 check port 3306 inter 10000 fall 2
    server read2 yanase-rr02.chmbfm8ojccp.ap-northeast-1.rds.amazonaws.com:3306 check port 3306 inter 10000 fall 2
    server master yanase.chmbfm8ojccp.ap-northeast-1.rds.amazonaws.com:3306 check port 3306 backup

負荷分散の動作確認

動作確認をすると負荷分散されている事が分かると思います。
$ mysql -u okochang -p -h 127.0.0.1
mysql> show variables like 'hostname'G
*************************** 1. row ***************************
Variable_name: hostname
        Value: ip-10-122-27-229
1 row in set (0.01 sec)

$ mysql -u okochang -p -h 127.0.0.1
mysql> show variables like 'hostname'G
*************************** 1. row ***************************
Variable_name: hostname
        Value: ip-10-134-139-130
1 row in set (0.00 sec)

リードレプリカを削除した後に接続すると、RDSのマスターに接続します。
$ mysql -u okochang -p -h 127.0.0.1
mysql> show variables like 'hostname'G
*************************** 1. row ***************************
Variable_name: hostname
        Value: ip-10-132-190-47
1 row in set (0.00 sec)

まとめ

監視用のユーザーを追加して少し設定を変更するだけでOKなので、簡単に適用する事が出来ますね:-)

参考リンク