こんにちは、@fujiwara です。
2013年を振り返ると、春の新卒研修での社内ISUCON、秋のISUCON予選と本選でずっとISUCONをやっていたような気がしていまして、さてそれ以外になにか……そういえばインフラ回りの仕事もしていましたね。
カヤックのサーバインフラ全体としては、Amazon Web Service(AWS) への移行が進んだ1年でした。いままで自社サーバでやっていたソーシャルゲームや、比較的アクセスが多いとある自社サービス(これは後ほど事例公開されるかも知れません) を、AWS上で構築したり移行したり、という仕事が多かったです。
AWSでサービスを構築する場合、MySQL については
- RDS を利用する
- EC2 インスタンス上に MySQL サーバを稼働させる
というどちらかの手段を取ることになります。
RDSはフェイルオーバーやバックアップを自動でやってくれますし、参照用Slave(Read replica)の追加もコンソールからぽちぽちでOK、というすばらしいサービスなのですが、深淵な理由で EC2 上に MySQL を構築する場合にはそのあたりをすべて自前で面倒をみる必要があります。
特に厄介なのがマスターが落ちた場合のフェイルオーバーですが、これについては MHA for MySQL というツールを利用することにしました。
MHAがやってくれるのは
- masterでの障害発生検出
- 障害発生時に slave の中で一番レプリケーションが進んでいるものを master に昇格させる (他の slave は新 master への slave として自動的に構成し直される)
という作業です。
master が移動した場合には、アプリケーションはそちらに向けて接続する必要がありますが、その部分については MHA 自体のサポートはなく、各自が用意したコマンドを指定して MHA から起動することで切り替えてね、という作りになっています。
ということで、その部分は自前で用意することになります。
MHA::AWS を作りました
前置きが長くなりましたが、AWS で MHA を動作する場合に、master 移動時のフェイルオーバーを支援するスクリプトを書いてみました。
https://github.com/fujiwara/MHA-AWS
数日前に書き始めたもので、一通り動作確認はしていますが実戦投入はまだ、現状αクオリティーな代物です。(ドキュメントもこれからです…)
Perl製ですので、適宜 cpanm
などでインストールすると、mhaws
というコマンドが利用できるようになります。
前提
- ENI (Elastic Network Interface) をひとつ master に付与するために用意し、その ENI のIPアドレスに対して各クライアントが接続する
- EC2インスタンスのタグ
Name
の値をホスト名として内部で名前解決できる - 各サーバ同士は root ユーザで ssh login できる
- aws-cli が利用できる
- 内部で AWS::CLIWrapper を使用しています。
動作の流れ
以下のような流れで動作します。
- MHA が障害検知
mhaws master_ip_failover --command stop
により ENI を障害が起きた旧 master のインスタンスから引き剥がすmhaws shutdown --command (stopssh|stop)
により、旧 master の mysqld を強制停止(sshが繋がる場合)、もしくはインスタンスごと停止(sshが不通の場合)- MHA が新 master を選出、レプリケーションの構成を組み替える
mhaws master_ip_failver --command start
により、ENI を新 master に付ける
MHA が master の障害を検知すると、各処理フェーズで設定ファイルで指定したコマンドが起動されます。それらのうち、
master_ip_failover_script
master_ip_online_change_script
shutdown_script
について、mhaws
コマンドが指定できるようになっています。
(report_script
、secondary_check_script
については機能を提供しませんので、別途用意する必要があります。)
設定ファイル
# /etc/masterha_default.cnf
master_ip_failover_script=mhaws master_ip_failover --interface_id=eni-xxxxxxxx
master_ip_online_change_script=mhaws master_ip_online_change --interface_id=eni-xxxxxxx
shutdown_script=mhaws shutdown --interface_id=eni-xxxxxxxx
--interface_id
には、master 用に用意した ENI の id を指定してください。
動作例
(ログが膨大になるので省略します……)
まだまだ簡単なテストしかしていない状態なので積極的におすすめはしがたいのですが、AWS で MHA を使おうかなあと思っているかたはお試しいただいて、フィードバックいただけると大変嬉しいです。
カヤックでは AWS に限らずサーバサイドで開発・運用できるエンジニアを募集しています!
明日は @Gemmbu さんです。お楽しみに!