MHA on AWS+Rails

44
MAH on AWS+Rails 2014/7/11 MySQL Casual Talks vol.6 クックパッド株式会社 菅原 元気

Transcript of MHA on AWS+Rails

Page 1: MHA on AWS+Rails

MAH on AWS+Rails2014/7/11 MySQL Casual Talks vol.6

クックパッド株式会社 菅原 元気

Page 2: MHA on AWS+Rails

お前誰よ

菅原 元気

@sgwr_dts / http://so-wh.at/● Ruby / AWS● https://bitbucket.org/winebarrel● https://github.com/winebarrel● 白金台の方から来ました

Page 3: MHA on AWS+Rails

最近のアクティビティ

便利スキーマ管理ツールを作りました

https://github.com/winebarrel/ridgepole

Page 4: MHA on AWS+Rails

最近のアクティビティ

数日後に同僚がもっと高性能なやつを

作りましたが…

Page 5: MHA on AWS+Rails

サマリ

● 弊社のMHA設定とかについて● RailsアプリにMHAを導入した話

Page 6: MHA on AWS+Rails

弊社のMHAまわり

Page 7: MHA on AWS+Rails

弊社のMHAまわり

Page 8: MHA on AWS+Rails

弊社のMHAまわり

● 基本的にMySQL on EC2● VPC Route Tableによる仮想IP● Rails 3.2 / 4.x

Page 9: MHA on AWS+Rails

弊社のMHAまわり

● フェイルオーバーまわりのツールは自作○ Route Tableの書き換えなど

● master_ip_failoverなどはPerlからポート+ VPCまわりの処理を追加

● サンプルプロジェクト:https://bitbucket.org/winebarrel/mha-example-for-aws (業務用とは若干異なります)

Page 10: MHA on AWS+Rails

弊社のMHAまわり

● ManagerはUpstartでデーモン化● 複数のクラスタを監視● 冗長化はしてません

Page 11: MHA on AWS+Rails

弊社のMHAまわり

● /etc/masterha_default.cnf○ サービスで共通な設定を記述○ ユーザ・ポート○ スクリプトのパス○ etc...

Page 12: MHA on AWS+Rails

弊社のMHAまわり

● /usr/local/masterha/conf/service1.cnf, service2.cnf…○ サービス毎の設定○ 作業ディレクトリの設定○ セカンダリチェックの設定○ ホスト名○ etc...

Page 13: MHA on AWS+Rails

弊社のMHAまわり

● /etc/sysconfig/mha.yaml○ 自作のmaster_ip_failover, master_ip_online_change

で使う情報を集約○ AWS APIのキー○ アラートメールの送信先○ サービス毎の仮想IP○ インスタンスID○ etc...

Page 14: MHA on AWS+Rails

弊社のMHAまわり

ノードサーバのPuppetclass { 'mha4mysql_node': virtual_ip => $vip_xxx }

● rpmのインストール● Source/Dest Checkの無効化● loへのIPの追加● ネットワーク設定ファイルの更新● etc...

Page 15: MHA on AWS+Rails

弊社のMHAまわり

マスターサーバのPuppet$mha_apps = { service1 => { hostname => 'service1-db-001', virtual_ip_address => $vip_serviec1_ipaddr, app_user => "'wriable_user'@'192.168.%'", slaves => ['service1-db-002', 'service1-db-002', 'service1-db-003'], autostart => true, }, ...

Page 16: MHA on AWS+Rails

弊社のMHAまわり

● MHA用設定ファイルの作成● Upstartの各種設定● etc...

Page 17: MHA on AWS+Rails

弊社のMHAまわり

MHA用のMySQLアカウント

GRANT RELOAD, PROCESS, SUPER ON *.* TO 'hoge'@'...' GRANT ALL PRIVILEGES ON `mysql`.* TO 'hoge'@'...'

Page 18: MHA on AWS+Rails

導入に至るまで

Page 19: MHA on AWS+Rails

導入にあたって

● 検証環境を作ってテストしました

Page 20: MHA on AWS+Rails

導入にあたって

● 検証環境を作ってテストしました● 仮想IPは切り替わりました

Page 21: MHA on AWS+Rails

導入にあたって

● 検証環境を作ってテストしました● 仮想IPは切り替わりました● スレーブも付け替わりました

Page 22: MHA on AWS+Rails
Page 23: MHA on AWS+Rails

500 Internal Server Error

Page 24: MHA on AWS+Rails

500 Internal Server Error

(当たり前ですが)

Railsでエラーが出ます

Page 25: MHA on AWS+Rails

Automatic Reconnectionhttp://dev.mysql.com/doc/refman/5.5/en/auto-reconnect.html

● 「reconnect: true」で自動再接続が有効に● サーバが死んでも再接続してくれる

Page 26: MHA on AWS+Rails

Automatic Reconnection

● 再試行は一回だけ● 「Access denied for user…」のような

エラーでは再接続しない

Page 27: MHA on AWS+Rails

activerecord-mysql-reconnect

再接続のためのライブラリを作りましたhttps://bitbucket.org/winebarrel/activerecord-mysql-reconnect

Page 28: MHA on AWS+Rails

activerecord-mysql-reconnect

MyApp::Application.configure do

... config.active_record.enable_retry = true config.active_record.execution_tries = 10 config.active_record.execution_retry_wait = 1.5 config.active_record.retry_mode = :rw

...

ene

Page 29: MHA on AWS+Rails

activerecord-mysql-reconnect

Page 30: MHA on AWS+Rails

activerecord-mysql-reconnectStarted GET "/items" for 127.0.0.1 at 2014-07-10 13:18:08 +0000Processing by ItemsController#index as */* Rendered items/index.html.erb within layouts/application (0.3ms)Completed 200 OK in 3.2ms (Views: 1.8ms | ActiveRecord: 0.6ms)Started GET "/items" for 127.0.0.1 at 2014-07-10 13:18:08 +0000MySQL server has gone away. Trying to reconnect in 1.5 seconds. (cause: Access denied for user 'scott'@'dagon' (using password: YES) [Mysql2::Error], connection: host=192.168.100.100;database=hello;username=scott)Started GET "/items" for 127.0.0.1 at 2014-07-10 13:18:08 +0000MySQL server has gone away. Trying to reconnect in 1.5 seconds. (cause: Access denied for user 'scott'@'dagon' (using password: YES) [Mysql2::Error], connection: host=192.168.100.100;database=hello;username=scott)MySQL server has gone away. Trying to reconnect in 3.0 seconds. (cause: Access denied for user 'scott'@'dagon' (using password: YES) [Mysql2::Error], connection: host=192.168.100.100;database=hello;username=scott)MySQL server has gone away. Trying to reconnect in 3.0 seconds. (cause: Access denied for user 'scott'@'dagon' (using password: YES) [Mysql2::Error], connection: host=192.168.100.100;database=hello;username=scott)Processing by ItemsController#index as */* Rendered items/index.html.erb within layouts/application (0.4ms)Completed 200 OK in 3.5ms (Views: 1.9ms | ActiveRecord: 0.9ms)

Page 31: MHA on AWS+Rails

activerecord-mysql-reconnect

実装

● フェイルオーバー時にエラーの出る下位レイヤのメソッドをフック

● エラーメッセージに応じて再試行○ 元の例外を取得できないもので、、、

参考) Rals 3.2 ActiveRecord:StatementInvalidhttps://github.com/rails/rails/blob/3-2-stable/activerecord/lib/active_record/errors.rb#L58

Page 32: MHA on AWS+Rails

セッションを切って大丈夫か?

クエリ以外のセッションに依存している

メソッドはない?

Page 36: MHA on AWS+Rails

セッションを切って大丈夫か?

まあ大丈夫じゃないかな…

Page 37: MHA on AWS+Rails

再接続モード

● :r (読み込み)○ SELECT / SHOW / SET をリトライ

● :rw(読み書き)

○ 「Lost connection to server during query」以外の

クエリをリトライ

● :force(全部)○ すべてのSQLをリトライします

Page 38: MHA on AWS+Rails

Lost connection to server during queryhttp://dev.mysql.com/doc/refman/5.5/en/gone-away.html

CR_SERVER_LOSTThe client didn't get an error when writing to the server, but it didn't get a full answer (or any answer) to the question.

Page 39: MHA on AWS+Rails

Lost connection to server during query

検証環境で発生しない…

Page 40: MHA on AWS+Rails

Lost connection to server during query

mysql2をいじる…● mysql_send_queryと

mysql_read_query_resultの間にsleepを入れる● クライアントからクエリを投げる● sleepの間にMySQLを再帰起動● sleepの間にMySQLをkill● エラーにならない…

Page 41: MHA on AWS+Rails

Lost connection to server during query

今のところはうまく動いてます…

Page 42: MHA on AWS+Rails

その後

● いろいろと検証して本番投入● とあるサービスでオンライン切り替え● エラーなし!

Page 43: MHA on AWS+Rails

Demo

Page 44: MHA on AWS+Rails