LoginSignup
43
20

More than 5 years have passed since last update.

Amazon AuroraのフェイルオーバーとRailsのコネクションプーリング

Last updated at Posted at 2016-12-26

ちょっと先日事故ったのでメモを兼ねて。

Auroraのフェイルオーバーの挙動

まずは、Auroraのフェイルオーバーの挙動。
従来のRDSではマスターデータベースをAZ構成にしておいてレプリカをぶら下げる構成だったが、Auroraからはデフォルトでクラスタになっている。

使用出来るエンドポイント

クラスタの真前をfailover-aurora、インスタンス名をfailover-aurora-instance という名前でauroraのクラスタを作ると以下の様なエンドポイントが得られる。

Cluster Endpoint

クラスターに対して書き込みをする用のエンドポイント。
こんな感じ。

failover-aurora.cluster-xxxx.ap-northeast-1.rds.amazonaws.com

Reader Endpoint

クラスターに対して読み込みをする用のエンドポイント。レプリカのどれかに紐づく様になっていて、書き込みをするとエラーになる。-roというsuffixが付く。

failover-aurora.cluster-ro-xxxx.ap-northeast-1.rds.amazonaws.com

各インスタンスのEndpoint

インスタンス毎にもエンドポイントが存在する。

マスター

failover-aurora-instance.xxxx.ap-northeast-1.rds.amazonaws.com

レプリカ (AZの名前がつくらしい)

failover-aurora-instance-ap-northeast-1a.xxxx.ap-northeast-1.rds.amazonaws.com

IPをひいてみると

実際のDNSレコードがどういう構成なのかIPを問い合わせてみる。

Cluster Endpoint

failover-aurora.cluster-xxxx.ap-northeast-1.rds.amazonaws.com. 5 IN CNAME failover-aurora-instance.xxxx.ap-northeast-1.rds.amazonaws.com.
failover-aurora-instance.xxxx.ap-northeast-1.rds.amazonaws.com. 5 IN A 172.30.25.134

Reader Endpoint

failover-aurora.cluster-ro-xxxx.ap-northeast-1.rds.amazonaws.com. 1 IN CNAME failover-aurora-instance-ap-northeast-1a.xxxx.ap-northeast-1.rds.amazonaws.com.
failover-aurora-instance-ap-northeast-1a.xxxx.ap-northeast-1.rds.amazonaws.com. 5 IN A 172.30.3.157

Cluster Endpointは、マスターデータベースを指すエンドポイントのCNAMEになっていて、Reader Endpointはレプリカを指すエンドポイントのCNAMEになっている事が分かる。

フィエルオーバー後のIP

実際にフェイルオーバーを起こした後に、IPがどう変化するかを確認する。

Cluster Endpoint

failover-aurora.cluster-xxxx.ap-northeast-1.rds.amazonaws.com. 1 IN CNAME failover-aurora-instance-ap-northeast-1a.xxxx.ap-northeast-1.rds.amazonaws.com.
failover-aurora-instance-ap-northeast-1a.xxxx.ap-northeast-1.rds.amazonaws.com. 5 IN A 172.30.3.157

Reader Endpoint

failover-aurora.cluster-ro-xxxx.ap-northeast-1.rds.amazonaws.com. 1 IN CNAME failover-aurora-instance.xxxx.ap-northeast-1.rds.amazonaws.com.
failover-aurora-instance.xxxx.ap-northeast-1.rds.amazonaws.com. 3 IN A 172.30.25.134

各インスタンスのIPに変化は無く、CNAMEの切り換えだけが行われている事が分かる。
ちなみに、興味深かったのはReader側のCNAMEのTTLが1秒でCluster側が5秒担っていた事。
昇格側はさっさと切り替わる方が障害時間が短くなるためか、slaveは複数台連なるので負荷分散の為の想定かそんなところだろうか。

Railがconnection poolingしている場合

で、本題のRailsのコネクションプーリングについて。

この辺りの記事が詳しい(むしろこれで話は終わりという感じ)。
http://blog.livedoor.jp/sonots/archives/38797925.html

マスターをAZ構成にしていた場合には、旧マスターは接続不可となるのでrailsは接続出来ないエラー共に再起動され、(設定によるが)ワーカーが再起動して新しいIPをひくので問題なかったが、
Auroraの用に、マスターがスレーブに降格する様な場合には、引き続きrailsは旧マスターに接続し続けられる為に、コネクションをプーリングし続けてしまい書き込みだけが出来ない様な状態になる。
エラーとしては以下の様なものが出力される。

Mysql2::Error: The MySQL server is running with the --read-only option so it cannot execute this statement

都度接続にする

解決策としては、コネクションプーリングをやめて都度接続にする事が手っ取り早い。以下の様なgemもあるためかなり簡単に設定出来る。
https://github.com/sonots/activerecord-refresh_connection

マスター切替以外でも

スレーブが複数台いる場合に、コネクションプーリングだとスレーブへのアクセスがかなり偏る可能性がある。
特に台数が少ないうちはかなり偏るはず。

まとめ

都度接続のコストが高くない限り、コネクションプーリングはやめたほうがいんじゃないかなと思いました。

43
20
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
43
20