2015サーバ屋日記2002年創業のインフラ屋さんです。サーバーの販売からWEBサービス系のクラスタシステム構築が得意です。AWS、GCP、オンプレ実績あります。2015の22日目のエントリです。Talksという勉強会で登壇してきました。その時の内容をまとめておきたいと思います。MySQLデータベースサーバに障害が起きた時、サービスを続けるには幾つかの方法があります。Utilitiesに含まれるmysqlfailoverというユーティリティーを利用する方法などです。今回、Keepalivedというソフトウェアと、MySQLの双方向レプリケーションを使って、ほぼ無停止でフェイルオーバーする構成を試してみたので、それについてまとめておきたいと思います。システム構成db1、db2という二つのサーバで、それぞれmysqldとkeepalivedを動かします。mysqldはお互いがMasterとなる双方向レプリケーションを行います。IP(VIP)を付与します。Masterということになります。双方向レプリケーションを行う場合に同時に両方のサーバへの書き込みを許可すると、データの不整合や、レプリケーションの停止を引き起こしてしまうことが知られています。今回VRRPスレーブに誤って書き込みが行われないようにスレーブにreadonly=1のフラグを立てておきます。db1のmysqldが停止ししkeepalivedのヘルスチェックに失敗した場合、db1のkeepalivedはFAULTステートに移行します。Masterステートに移行しVIPが付与され、クライアントからのアクセスはdb2に向かうようになります。db2のkeepalivedがMasterに昇格する際には、スクリプトによりreadonly=0となり書き込みが可能になるようにしています。する必要がなくシンプルであることがメリットだと考えられます。Protocol)は、もともと2台のルーターの冗長化のために作られたプロトコルで、RFCで規定されています。2の動きを説明するものです。v2では、プライオリティに基づいてMasterとBackupサーバーが決定され、MasterのみがVRRPアドバタイズパケットを予め定められた間隔、例えば1秒間隔で送信します。Masterからのアドバタイズパケットが一定期間途切れると、BackupサーバがMasterサーバに状態遷移します。ヘルスチェックKeepalivedのVRRPデーモンには、RFCで規定されたVRRPプロコルの機能に加え、おまけとしてヘルスチェック機能があります。これによりスクリプトでmysqldの死活を監視し、監視が失敗するとKeepalivedのステータスをFAULTに遷移させることができます。この場合プライオリティ=0のVRRPアドバタイズパケットが送信され、直ちにBackupサーバがMasterに昇格します。以下の設定は、keepalivedの設定ファイルの一部ですが1秒に一回ヘルスチェックスクリプト"/etc/keepalived/vrrp/mysqlchk.sh"を実行し、二回失敗したらFAULTステートにし、2回成功するとBACKUPかMASTERに戻しています。'server_id';"に応答できるかどうかを確認しています。障害時にVRRPのフェイルオーバーにかかる時間は、大まかに以下のふた通りに分けることができます。Advertパケットを送信します。これを受信したBACKUPステートにいるkeepalivedは直ちにMASTERに昇格します。フェイルオーバーにかかる時間は、FAULTステート遷移に必要な2秒程度です。元のサーバからのVRRPパケットが途絶え、BACKUPステートにいるkeepalivedがMASTERステートに昇格します。VRRPアドバタイズパケットの間隔、すなわちAdvertisement_Intervalが1秒の場合は4秒程度でフェイルオーバーが完了します。以上により、この仕組みを利用する場合、2秒または4秒程度でフェイルオーバーが完了することになり、かなり速いと言って良いのではないでしょうか。今回のシステム構成では、db1とdb2の間で双方向のレプリケーション構成にしています。この構成には落とし穴があるので、まず簡単にレプリケーションの仕組みをおさらいしておきたいと思います。次の図で、db1でコミットされたトランザクションはbinlogに記録されます。binlogに記録されたトランザクションは、ネットワークを介してdb2に送られIOスレッドによりrelaylogに書き込まれ、SQLスレッドによりテーブルスペースに順次コミッされていきます。したがって、db1で完了したコミットはすぐにSlaveのテーブルスペースに書き込まれるわけではなく、有限時間の遅延が発生します。レプリケーションのSQLスレッドは、mysqld-5.6までは1スキーマに対して1スレッドでしか実行できないので、SQLスレッドによるテーブルスペースへのコミットが追いつかずrelaylogにデータが溜まっていく場合が、時々見られます。レプリケーションが遅延している時に、VRRPのフェイルオーバーが起こると以下の図のような状態になります。relaylogに溜まっているデータはSQLスレッドにより順次コミットされていきますが、同時にクライアントからの書き込みが行われると、データに不整合が起こりレプリケーションが停止する場合があります。今回の構成ではこれを防ぐために、フェイルオーバー時にVIPがdb2に移った時、すぐに書き込み可能な状態にするのではなく、レプリケーションの遅延がなくなるのを待っててreadonly=0をセットするようにしています。まとめ今回、keepalivedのVRRP機能と、MySQLの双方向レプリケーションを組み合わせた、MySQLサーバの冗長化について試してみました。良いところおよそ4秒以内、ほぼ瞬時にフェイルオーバーする。フェイルオーバー時にレプリケーション関連のオペレーションが入らないので、シンプルである。課題マルチマスターなので不整合に気をつけるrepが遅いとなかなか昇格できない。MySQL5.7に期待。共有2015年10月29日木曜日マイKVM環境を晒しておきます。environment.皆さん、こんにちは。最近、寒暖差が激しいので、お体には気をつけてくださいね。Jessie用のKVM環境をご紹介します。Machineの略で、Linuxのカーネルで実装された仮想マシンハイパーバイザーのことです。一般的には、ハイパーバイザー自体を指すよりも、それを用いた仮想マシンの方式のことを指す場合も多いかと思います。弊社ではKVMによる仮想環境を用い、各種サーバプログラム、WEBクラスターなどの検証を行っています。最近のLinuxディストリビューションでは、すでに簡単な操作で仮想マシンを立ち上げることが可能です。kvmが最初にバニラカーネルに組み込まれたlinux-2.6.20の頃から自家製スクリプトでkvm仮想マシンを利用しており、それが使い易く、興味を持ってくれる人もいるかもしれないのでここに公開する次第です。仮想マシンの抽象化ライブラリであるlibvirtを介さずGUIなども無いので、比較的仕組みが理解しやすくカスタマイズが簡単であることがメリットかと考えています。カーネルの最新機能や最新のqemuに追従することもたやすくできます。それでですね、ものはここにおいてあります。allするを行えばオッケーです。busyboxとkernelのコンパイル時にmenuconfig画面が表示されますが、通常はそのままExitしてください。何か思うところがあってカスタマイズしたい場合は、そこでカスタマイズを行ってください。仮想マシンの実行は、/kvm/sbin/kvmスクリプトで行います。domainソケットを通してのqemuプロセスの制御です。v001という仮想マシンを起動してみます。v001が生きているかどうかは、次のように確認できます。次にv002を起動し、状態を確認してみます。稼働中の仮想マシンの一覧は、以下のように確認できます。conのカラムはコンソールソケット、monのカラムはモニターソケット、imgのカラムはVMのイメージファイルの状態を表しています。uとなっていますが、これはコンソール、モニターの両ソケットが接続可能で、イメージファイルが使用中(VMが稼働中)であることを表しています。今度は、v001のコンソールに接続してみます。コンソールに接続するとログインプロンプトが表示されるのでroot/rootでログインします。rootのパスワードはMakefileにベタ書きしてあり、イメージtemplate作成時に設定されます。コンソール接続を終了するには"Ctrl+]"をタイプします。テンプレートイメージ作成時には、/root/.ssh/authorized_keysもコピーしていますので、ホストのマシンと同じ鍵でsshログインすることが可能です。v001のIPアドレスはinitrdの中で172.16.1.1を決め打ちで設定しています。v002の場合は172.16.1.2、v250の場合は172.16.1.250が割り当てられ、v250を上限にしてあります。これらのホスト名、IPは、セットアップ時にホストの/etc/hostsに追記してあります。ゲストマシンからは、ホストマシンのNATを介して外部のネットワークと通信が可能です。同じホスト上の仮想マシン間で通信することも可能です。別ホストからは、直接仮想マシンにアクセスできないようになっていますので、別ホスト上の仮想マシンとは通信できません。したい場合は、ブリッジとvlanの設定を工夫することで、通信可能になるでしょう。仮想マシンを停止したいときは、仮想マシンにログインしpoweroffを実行するか、以下のようにshutdownコマンドを発行します。listコマンドで見ると、停止しているv001は以下のように見えます。v001のイメージを完全に消したいときは、仮想マシンが停止した状態で、/kvm/data/v001.imgを消してください。だいたい使い方は以上になります。