MySQLの大きな機能であるレプリケーションを利用する場合にデフォルト設定での運用は難しい気がします。というのもサーバは絶え間なく動いているようですが、VPSやクラウドなどではクラウド業者のネットワーク不調による瞬断やハイパーバイザの高負荷に通信不調、メンテナンス等の様々な要因や影響で完全に安定した通信の継続は難しいものです。
2015年、365日のあいだ一度も落ちなかったクラウドはあるか?
>Amazonクラウドの項目を見てみましょう。Amazon EC2は過去1年の稼働率が99.9992%。2回の障害があり、合計で16.88分、リージョンあたり4.22分のダウンタイムがあったとされています。
>Google Compute Engineは、過去1年の稼働率が99.9757%、合計で2.13時間のダウンタイムがありました。11月に欧州西リージョンで70分ものあいだネットワーク接続が切れるという障害が発生していたので、それが響いているのではないかと考えられます。
>マイクロソフトのMicrosoft AzureのMicrosoft Azure Virtual Machinesの稼働率は99.9996%。合計で40.07分、リージョンあたり10.02分のダウンタイムがあったとのこと。
>そしてIBMのSoftLayerではSoftLayer Cloud Serversの稼働率が100%と報告されています。ただしこの数字は障害を十分検知できなかったとの注意が付いており、合計で45.36分、リージョンあたり7.61分のダウンタイムがあると報告されています。
@see 2015年、365日のあいだ一度も落ちなかったクラウドはあるか? AWSやAzureなど主要クラウドのダウンタイムについてCloud Harmonyの調査結果
結果的に落ちないクラウドが存在しないという状態。
しかも、まとめた時間にダウンするわけじゃなくて、上位クラウドのネットワークや負荷なりで不安定になり、数秒なりぷつぷつ切れて接続が出来ていないことがあります。それに加えて、ミドルウェアの不調やサービス利用の負荷などもあるのでさらにダウンタイムが発生します。
だからといって、接続が切れる度にレプリケーションを手動で接続しなおすのは大変なので、きちんとレプリケーションの再接続設定の値を把握しておくとゆっくり寝られるはず。サーバは落ちることを前提に設計を行い、落ちても復旧出来るように、落ちた時のリカバリを考えて設計しておくのが大切だと考えています。
スレーブからマスターへ接続するSQL文
MySQLのレプリケーションというと下記のようにスレーブからマスターに接続をかけます。
1 |
mysql> CHANGE MASTER TO MASTER_HOST='153.xxx.yyy.10', MASTER_USER='replicationuser', MASTER_PASSWORD='パスワード', MASTER_CONNECT_RETRY=10, MASTER_LOG_FILE='mysql-bin.000008', MASTER_LOG_POS=120; |
レプリケーション再接続時の時系列
1 2 3 4 5 6 7 8 9 10 11 12 |
==+======================+=========================+=========================+========> | | | | | | | | |<-------------------->|<----------------------->|<----------------------->| | slave_net_timeout秒 | master-connect-retry秒 | master-connect-retry秒 | | | (default 60秒) | | | 再接続試行 再接続試行 | | <---------------------------> | master-retry-count回繰り返す | (default 86400回) master停止 |
この図を考慮にいれて値を把握しながら設定していきます。
–slave-net-timeout=秒数
スレーブが読み取りを中止する前に、マスタからのデータを待つ秒数。
スレーブが接続切断と判断して再接続を試行するときのもの。最初の接続試行はタイムアウト直後に行われる。再試行のインターバルは、–master-connect-retry オプションでコントロールできる。再接続の試行回数は –master-retry-count オプションで設定する。デフォルトでは、3600 秒 (1時間)。
@see http://masasuzu.hatenablog.jp/entry/2013/01/18/mysql_master_connect_retry
デフォルトの1時間は長すぎなので、10秒程に設定することが多いです。
–master-connect-retry=秒数
マスタがダウンするか接続不可の場合にマスタへ再接続を試行する前に、スレーブ スレッドがスリープ状態になる秒数。master.info ファイルの値が読み込れる場合、その値が優先される。設定しなければ、デフォルトで 60 秒。
–slave-net-timeout の値に基づくマスタからのデータ読み込みに対してタイムアウトするまで、
スレーブによる再接続の自動呼び出しは行われない。再接続の試行の回数は、–master-retry-count で制限する。
@see http://masasuzu.hatenablog.jp/entry/2013/01/18/mysql_master_connect_retry
60秒は長すぎるので、10秒程に設定することが多いです。
–master-retry-count
(デフォルト:86400回)
@see http://masasuzu.hatenablog.jp/entry/2013/01/18/mysql_master_connect_retry
マスターへのレプリケーション接続試行回数。この値はデフォルトそのままに。
基本的には上記の内容で設定しています。
さらにレプリケーションのヘルスチェックの監視スクリプトを作成し、異常を通知する仕組みをつくると運用として良いです。リスク管理も捗ります。