Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

MHA on AWS+Rails

Related Books

Free with a 30 day trial from Scribd

See all
  • Login to see the comments

MHA on AWS+Rails

  1. 1. MAH on AWS+Rails 2014/7/11 MySQL Casual Talks vol.6 クックパッド株式会社 菅原 元気
  2. 2. お前誰よ 菅原 元気 @sgwr_dts / http://so-wh.at/ ● Ruby / AWS ● https://bitbucket.org/winebarrel ● https://github.com/winebarrel ● 白金台の方から来ました
  3. 3. 最近のアクティビティ 便利スキーマ管理ツールを作りました https://github.com/winebarrel/ridgepole
  4. 4. 最近のアクティビティ 数日後に同僚がもっと高性能なやつを 作りましたが…
  5. 5. サマリ ● 弊社のMHA設定とかについて ● RailsアプリにMHAを導入した話
  6. 6. 弊社のMHAまわり
  7. 7. 弊社のMHAまわり
  8. 8. 弊社のMHAまわり ● 基本的にMySQL on EC2 ● VPC Route Tableによる仮想IP ● Rails 3.2 / 4.x
  9. 9. 弊社のMHAまわり ● フェイルオーバーまわりのツールは自作 ○ Route Tableの書き換えなど ● master_ip_failoverなどはPerlからポート + VPCまわりの処理を追加 ● サンプルプロジェクト: https://bitbucket.org/winebarrel/mha- example-for-aws (業務用とは若干異なります)
  10. 10. 弊社のMHAまわり ● ManagerはUpstartでデーモン化 ● 複数のクラスタを監視 ● 冗長化はしてません
  11. 11. 弊社のMHAまわり ● /etc/masterha_default.cnf ○ サービスで共通な設定を記述 ○ ユーザ・ポート ○ スクリプトのパス ○ etc...
  12. 12. 弊社のMHAまわり ● /usr/local/masterha/conf/service1.cnf, service2.cnf… ○ サービス毎の設定 ○ 作業ディレクトリの設定 ○ セカンダリチェックの設定 ○ ホスト名 ○ etc...
  13. 13. 弊社のMHAまわり ● /etc/sysconfig/mha.yaml ○ 自作のmaster_ip_failover, master_ip_online_change で使う情報を集約 ○ AWS APIのキー ○ アラートメールの送信先 ○ サービス毎の仮想IP ○ インスタンスID ○ etc...
  14. 14. 弊社のMHAまわり ノードサーバのPuppet class { 'mha4mysql_node': virtual_ip => $vip_xxx } ● rpmのインストール ● Source/Dest Checkの無効化 ● loへのIPの追加 ● ネットワーク設定ファイルの更新 ● etc...
  15. 15. 弊社の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, }, ...
  16. 16. 弊社のMHAまわり ● MHA用設定ファイルの作成 ● Upstartの各種設定 ● etc...
  17. 17. 弊社のMHAまわり MHA用のMySQLアカウント GRANT RELOAD, PROCESS, SUPER ON *.* TO 'hoge'@'...' GRANT ALL PRIVILEGES ON `mysql`.* TO 'hoge'@'...'
  18. 18. 導入に至るまで
  19. 19. 導入にあたって ● 検証環境を作ってテストしました
  20. 20. 導入にあたって ● 検証環境を作ってテストしました ● 仮想IPは切り替わりました
  21. 21. 導入にあたって ● 検証環境を作ってテストしました ● 仮想IPは切り替わりました ● スレーブも付け替わりました
  22. 22. 500 Internal Server Error
  23. 23. 500 Internal Server Error (当たり前ですが) Railsでエラーが出ます
  24. 24. Automatic Reconnection http://dev.mysql.com/doc/refman/5.5/en/auto-reconnect.html ● 「reconnect: true」で自動再接続が有効に ● サーバが死んでも再接続してくれる
  25. 25. Automatic Reconnection ● 再試行は一回だけ ● 「Access denied for user…」のような エラーでは再接続しない
  26. 26. activerecord-mysql-reconnect 再接続のためのライブラリを作りました https://bitbucket.org/winebarrel/activerecord-mysql-reconnect
  27. 27. 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
  28. 28. activerecord-mysql-reconnect
  29. 29. activerecord-mysql-reconnect Started GET "/items" for 127.0.0.1 at 2014-07-10 13:18:08 +0000 Processing 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 +0000 MySQL 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 +0000 MySQL 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)
  30. 30. activerecord-mysql-reconnect 実装 ● フェイルオーバー時にエラーの出る 下位レイヤのメソッドをフック ● エラーメッセージに応じて再試行 ○ 元の例外を取得できないもので、、、 参考) Rals 3.2 ActiveRecord:StatementInvalid https://github.com/rails/rails/blob/3-2- stable/activerecord/lib/active_record/errors.rb#L58
  31. 31. セッションを切って大丈夫か? クエリ以外のセッションに依存している メソッドはない?
  32. 32. セッションを切って大丈夫か? last_id ActiveRecord → mysql2 → libmysql/libmysql.c my_ulonglong STDCALL mysql_insert_id(MYSQL *mysql) { return mysql->insert_id; }
  33. 33. セッションを切って大丈夫か? affected_rows ActiveRecord → mysql2 → libmysql/libmysql.c my_ulonglong STDCALL mysql_affected_rows(MYSQL *mysql) { return mysql->affected_rows; }
  34. 34. セッションを切って大丈夫か? quote_string / escape ActiveRecord → mysql2 → libmysql/libmysql.c → mysys/charset.c#escape_quotes_for_mysql → mysys/charset.c#escape_string_for_mysql (どちらも状態を持たない処理)
  35. 35. セッションを切って大丈夫か? まあ大丈夫じゃないかな…
  36. 36. 再接続モード ● :r (読み込み) ○ SELECT / SHOW / SET をリトライ ● :rw(読み書き) ○ 「Lost connection to server during query」以外の クエリをリトライ ● :force(全部) ○ すべてのSQLをリトライします
  37. 37. Lost connection to server during query http://dev.mysql.com/doc/refman/5.5/en/gone-away.html CR_SERVER_LOST The 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.
  38. 38. Lost connection to server during query 検証環境で発生しない…
  39. 39. Lost connection to server during query mysql2をいじる… ● mysql_send_queryと mysql_read_query_resultの間にsleepを入れる ● クライアントからクエリを投げる ● sleepの間にMySQLを再帰起動 ● sleepの間にMySQLをkill ● エラーにならない…
  40. 40. Lost connection to server during query 今のところはうまく動いてます…
  41. 41. その後 ● いろいろと検証して本番投入 ● とあるサービスでオンライン切り替え ● エラーなし!
  42. 42. Demo

×