share facebook facebook2 twitter menu hatena pocket slack

2013.03.05 TUE

MySQL ProxyでRDSを中継したときの(RDSの)フェイルオーバー対策

鈴木 宏康

WRITTEN BY 鈴木 宏康

以前、ELBのDNS名に関連付けられているIPアドレスが変更された際、HAProxyをリロードする仕組みを
HAProxyをDNS名で指定したバックエンドのIPアドレスが変わったらリロードするの記事で紹介しました。
今回、RDS(MySQL)とMySQL Proxyで同様の動作をするようにしてみました。
(VPC外からRDSにアクセスする場合にMySQL Proxyを中継するケースです)

※RDS(MySQL)はDNS名がsuzuki.xxx.ap-northeast-1.rds.amazonaws.comで作成済みとします。

○MySQL Proxyの準備


# yum -y install mysql-proxy
...

# cat /etc/sysconfig/mysql-proxy
# Options for mysql-proxy
PROXY_USER="mysql-proxy"
PROXY_OPTIONS="--daemon --log-level=info --log-use-syslog --keepalive --defaults-file=/etc/my.cnf"

# cat /etc/my.cnf
[mysql-proxy]
proxy-address=:3306
proxy-backend-addresses=suzuki.xxx.ap-northeast-1.rds.amazonaws.com:3306

# diff /etc/init.d/mysql-proxy.bak /etc/init.d/mysql-proxy
23,25d22
< ADMIN_USER="admin"
< ADMIN_PASSWD=""
< ADMIN_LUA_SCRIPT="/usr/lib64/mysql-proxy/lua/admin.lua"
39c36
< daemon $prog $PROXY_OPTIONS --pid-file=$PROXY_PID --user=$PROXY_USER --admin-username="$ADMIN_USER" --admin-lua-script="$ADMIN_LUA_SCRIPT" --admin-password="$ADMIN_PASSWORD"
---
> daemon $prog $PROXY_OPTIONS --pid-file=$PROXY_PID --user=$PROXY_USER

ADMIN関係の設定が利用できなかったため、デフォルトの/etc/sysconfig/mysql-proxyと
/etc/init.d/mysql-proxyからADMIN関係の記載を外しています。

○RDS(MySQL)への接続


# mysql -u suzuki -p -h 127.0.0.1
...
mysql> show databases;
...
5 rows in set (0.01 sec)

127.0.0.1(MySQL Proxy)に接続すると、自動的にRDS(MySQL)に接続されます。

○RDSがフェイルオーバーした場合の挙動

上記のようにRDSを手動でフェイルオーバーさせると、MySQL Proxyは下記のように接続できなくなります。


mysql> show databases;
ERROR 2013 (HY000): Lost connection to MySQL server during query

○RDSがフェイルオーバーした場合にMySQL Proxyをリスタート

基本は最初に紹介したブログ「HAProxyをDNS名で指定したバックエンドのIPアドレスが変わったらリロードする」の
通りです。

下記のファイル(スクリプト)でMonitによるチェックと再起動を実現しています。


# cat /etc/monit.d/check_dns_ip_rds.conf
check program check_dns_ip_rds with path "/opt/suz-lab/etc/monit/check_dns_ip_rds.sh"
if status != 0 then exec "/etc/init.d/mysql-proxy restart"

# cat /opt/suz-lab/etc/monit/check_dns_ip_rds.sh
#!/bin/sh
DNS_NAME=suzuki.xxx.ap-northeast-1.rds.amazonaws.com
set -e
trap 'echo "NG: $?"' ERR
/opt/suz-lab/lib/nagios/check_dns_ip -n $DNS_NAME
exit $?

○MySQL Proxyの自動リスタート


# cat /var/log/messages
... monit[9138]: 'check_dns_ip_rds' status failed (2) for /opt/suz-lab/etc/monit/check_dns_ip_rds.sh. Error: no output to stderr..
... monit[9138]: 'check_dns_ip_rds' exec: /etc/init.d/mysql-proxy
... mysql-proxy: 2013-02-27 15:12:44: (message) Initiating shutdown, requested from signal handler
... mysql-proxy: 2013-02-27 15:12:44: (message) shutting down normally, exit code is: 0
... mysql-proxy: 2013-02-27 15:12:44: (message) chassis-unix-daemon.c:176: [angel] PID=9206 exited normally with exit-code = 0 (it used 1 kBytes max)
... mysql-proxy: 2013-02-27 15:12:44: (message) Initiating shutdown, requested from mysql-proxy-cli.c:604
... mysql-proxy: 2013-02-27 15:12:44: (message) shutting down normally, exit code is: 0
... mysql-proxy: 2013-02-27 15:12:45: (message) chassis-unix-daemon.c:136: [angel] we try to keep PID=9345 alive
... mysql-proxy: 2013-02-27 15:12:45: (message) mysql-proxy 0.8.2 started
... mysql-proxy: 2013-02-27 15:12:45: (message) proxy listening on port :3306
... mysql-proxy: 2013-02-27 15:12:45: (message) added read/write backend: suzuki.xxx.ap-northeast-1.rds.amazonaws.com:3306

上記よりRDSをフェイルオーバーするとMonitがDNS名に関連づけられたIPアドレスが変更されたことを検知して、
MySQL Proxyがリスタートされていることがわかり、下記のように今まで同様RDS(MySQL)に接続できることが
確認できます。


# mysql -u suzuki -p -h 127.0.0.1
...
mysql> show databases;
...
5 rows in set (0.01 sec)

こちらの記事はなかの人(suz-lab)監修のもと掲載しています。
元記事は、こちら

鈴木 宏康

鈴木 宏康

愛知県生まれ。東京工業大学大学院修士課程修了。在学時より、ベンチャー企業でインターネットに関する業務に携わり、現在はクラウド(主にAmazon Web Services)上での開発・運用を軸とした事業の、業務の中心として活躍。