中小規模のオンプレWebシステム(DBとしてMySQLを使用)をAWS環境(Auroraを使用)に移行する際に躓いたポイントをいくつか記録しておきます。
0. 前提
移行前、移行後の環境として、以下のようなものを想定してください。
0-1. 移行前
- VMwareによる仮想環境
- ストレージはエントリレベル(10G-iSCSI)
- MySQLは5.5/バイナリログあり/sync_binlog=1(遅い!)、複数あるがメインは1台
- データ量は1TiB未満
- DR:DBなどでのDBサーバ冗長化は行っていない
- Webサーバは数台(Java8(G1GC)/Tomcat8)
- Web~DB間のコネクションプーリングあり(DBCP2)
0-2. 移行後
- WebサーバはほぼそのままEC2へ(東京リージョンAZ-a/cに等分して配置)、ALBを使用
- Auroraはr3.xlarge~2xlarge程度、Multi-AZ、バイナリログあり(sync_binlog=1固定)、KMSで暗号化
1. 事前検証時
小規模なインスタンスを使って動作検証および軽い負荷テストを行った時点では、特に問題はありませんでした。
しかしその後、Auroraを冗長化してフェイルオーバー試験を行い始めたときに、問題が発生。
1つ目は、テスト用のAuroraクラスタ/インスタンスを削除する際のミスによる**「あれ?フェイルオーバーしない」**問題。
2つ目は、JavaのDB Connectorの選択問題。
Java環境向けにはAurora Driverを含むMariaDB Connector/J(1.2.0以降)があり、これを使えばAuroraのフェイルオーバーに対応できますが、
- (使用中の)MySQL Connector/Jと細部の挙動が違う(パラメータで調整可能なものもあるが全て合わせるのは難しい)
- Connector/Jから返される値の型や評価結果が違うことがある(これはアプリケーション側のコードの品質の問題ですが…)
ということで、断念。
結局、MySQL Connector/Jのまま、以下の対応を行うことに。
但し、プールしたコネクションの有効性確認にValidation Queryを使う「古い方法」でありパフォーマンス面ではあまりよろしくないです(対症療法です…)。
また、負荷を上げてフェイルオーバーを行うと**「切れたコネクションプールの回収処理が詰まる」という3つ目の問題が発生。
当初はコネクションプーリングを外したり(接続負荷が低いMySQLがベースとはいえ処理が遅くなってしまったので断念)、プーリングのパラメータ調整で何とかしようと試行錯誤しましたが、「JavaのGCが追いついていない」**のを見て、G1GCの目標時間(-XX:MaxGCPauseMillis)を調整して改善しました(オンプレ時は処理時間が短く済んでいたので、デフォルト値よりも短くしていました)。
※GCとして、G1GCではなくCMSを使っている場合も同様に「GCが追い付かなくなる」問題が出る可能性があります。
なお、速度改善のため、TomcatのコネクションプーリングをDBCP2からTomcat JDBC Connection Poolに変えてみましたが、一部のクエリの実行順序・タイミングに問題が見られたので、こちらも断念しました(調査・検証期間が足りず…)。
また、Auroraとは直接関係ありませんが、ALBでDraining時のリクエストが一部受け付けられずタイムアウトする問題が発生。
こちらはサポートから「現象は確認しており改善方法を検討しましたが困難なため、現時点では『仕様』ということになります」という主旨の回答を受けました。
2. データ移行時
AWSにはDMSもあるのですが、MySQLレプリケーションのほうが慣れているので、
- ある定点のバックアップを初期データとしてmysqldump形式でS3バケットへ(バケットは暗号化しておきましょう)
- ↑のS3バケットをEC2インスタンスからgoofysで読み取りマウントして、Auroraへリストア
- 定点からの差分はMySQLレプリケーションを使って反映
- 移行作業当日は、レプリケーションを切ってオンプレ側からAWS側にDNSのレコードを切り替える
- 万一のために、オンプレ側に切り戻し用の環境を作っておく(オンプレ側マスタDBがMySQL 5.5のため、切り戻し用にはMySQL 5.6を用意)
という形での移行を進めました。
まず、オンプレMySQL⇒Auroraのレプリケーションを行うときに、**「レプリケーション元とレプリケーション先で時間がずれる」**問題が発生。
続いて、オンプレ側切り戻し環境へのレプリケーションを行う際に、**「スレーブでマスタの指定ができない(エラーになる)」問題と「レプリケーションが止まる」**問題が相次いで発生。
慣れていても、油断は禁物ですね。
特に前者は、そもそもオリジナルのDBの初期設定時の設定漏れが原因ですので…。
なお、切り戻し環境としてオンプレ環境をAuroraのスレーブにするときには、オンプレMySQL側に以下の記事の**「3. rds_heartbeat2の作成」**の作業も必要です。
これをしていなくても、Aurora⇒MySQL(RDS以外)のレプリケーションが止まります。
- Amazon RDS のレプリケーションをEC2で行う。(koooheiさんの記事)
※その2に続きます。
【おまけ】
Amazon Aurora関連投稿記事へのリンクを集めました。