Upload
yoshinori-matsunobu
View
44.575
Download
4
Embed Size (px)
DESCRIPTION
Citation preview
1
MHA for MySQLによるDeNAのMySQL高可用ソリューションとDeNAにおけるオープンソースへの取り組み
株式会社 ディー・エヌ・エー
MySQL Geek, Oracle ACE Director
松信 嘉範 (MATSUNOBU Yoshinori)
Twitter: @matsunobu
2
自己紹介
� MySQL/Linux周りのスペシャリスト� 2006年9月から2010年8月までMySQL本家
(MySQL/Sun/Oracle)でAPAC/US圏のMySQLコンサルティングに従事
�主な著書に「現場で使えるMySQL」「Linux-DBシステム構築/運用入門」「Javaデータアクセス実践講座」
�日本で2人目のOracle ACE Director (WW MySQLでは4人目)
� 主に海外での講演�MySQL Conference and Expo 2011
�OSCON (2011.7)
�Oracle Open World (2011.10)
� Percona Live London (2011.10)
3
アジェンダ
� マスター自動フェイルオーバーの実現
� マスター無停止メンテの実現
� デモ
� DeNAにおけるオープンソースへの取り組み
4
Mobageの規模
� 1日あたり20数億PV以上
� 1000台以上のDB(MySQL)サーバ、それ以上のWebサーバ
� 国内だけで数拠点のデータセンター
� 数百を超えるアプリケーション
5
単一障害点を無くしたい
� Single Point of Failure: その箇所がダウンするとサービスが
止まる
� いかなる時にも緊急対応が必要になる� 早朝だろうと深夜だろうと対応が必要
� アプリの数が多ければ確率も上がる
� メンバーも疲弊する
� MySQLの世界では� スレーブは冗長化によってSPoFでなくすことは簡単
� マスターは1個しか無いから難しい
6
MySQLマスター障害対応の課題
id=99
id=100
id=101
id=102
master
slave1 slave2
id=99
id=100
id=99
id=100
id=101
・MySQLのレプリケーションは非同期または
準同期
・マスター障害時に、一部のスレーブ(あるいは全部のスレーブ)が
最新のバイナリログを受け取っていない可能性がある
・スレーブ間で、バイナリログの転送状況にずれが生じている可能性がある・左図の例では、id=102はどのスレーブにも
転送されていない・id=101はスレーブ2にしか転送されていない・スレーブ3ではid=100, id=101を受け取っていない
正しく復旧するには、・id=102をマスターから転送する
・スレーブ間でのずれを解消する必要がある
これを全自動でやるのがMHA
slave3
id=99
Writer IP
1. Save binlog events that
exist on master only
2. Identify which events are not sent
id=101id=100
id=101
3. Apply lost events
id=102 id=102 id=102
7
MHAのアーキテクチャ
� マスターの稼働監視およびダウン時の自動フェイルオーバーを実現するツール� http://code.google.com/p/mysql-master-ha/ にてOSSで公開� Pure Perl
� MySQL 5.0以降で動作� 管理サーバ(MHA Manager)と、個々のMySQLサーバでバイナリログの
差分修復等を行うツール(MHA Node)から構成される� モジュールの依存関係は少ない
– NodeパッケージはDBD::mysqlのみ– ManagerパッケージはConfig::Tiny, Log::Dispatch, Parallel::ForkManager, DBD::mysql,
MHA::Nodeに依存しているが、だいたい1-2箇所に入れれば十分
master
slave1 slave2 slave3
Manager
mha4mysql-manager
- masterha_manager
- masterha_master_switch
mha4mysql-node
- save_binary_logs
- apply_diff_relay_logs
- purge_relay_logs
master
slave1 slave2 slave3
8
内部的な動作
Final Relay_Log_File,
Relay_Log_Pos
Master_Log_File
Read_Master_Log_Pos
Latest SlaveDead Master
(i1)
(i2)
(X)
Slave(i)
Wait until SQL thread
executes all events
� SQLスレッドが実行を終えるまで待つ (i1)
� 最新スレーブのリレーログログのヘッダを解析して各スレーブに適用すべき差分位置を特定(i2)
� マスターにアクセス可能なら、マスターから差分を保存(X)
� i1->i2->Xをすべて組み立て1個のバイナリログにする (Format Description Eventは内部的にROLLBACKを生成しうるので先頭のみ)
� mysqlbinlogして実行� 上記をスレーブ間で並列で行なう
9
主な特徴
� マスターの稼働監視からフェイルオーバーまでを自動でできる� フェイルオーバーを手動で行なうことも可能
� フェイルオーバーが秒単位で可能� アクティブ/アクティブ型のため
� 非同期レプリケーションにもかかわらず、スレーブ間での同期が取れている
� 任意のスレーブを新マスターにできる
� いくつかの箇所から外部スクリプトを呼ぶ機能(拡張ポイント)がある� 電源OFFやIPアドレスのフェイルオーバーなどに使う
10
主な特徴
� MySQL5.0以降であれば標準のMySQLで動作する
� インストール/アンインストールにあたり現在のmysqldプロセスやレプリケーションを止める必要が無い
� MHA自体は追加の負荷をかけないため、パフォーマンスが低下せず、追加のサーバも不要
� ストレージエンジンに依存しない
� バイナリログのフォーマットに依存しない� StatementベースでもRowベースでも大丈夫
11
拡張ポイント� seconary_check_script
� マスターがダウンしたかどうかを複数のNW経路から判定するために呼ばれる
� マスターに接続エラーになった時に呼ばれる� MHAに標準搭載しているスクリプトmasterha_seconary_check が便利
� shutdown_script� 電源強制OFFなど
� フェイルオーバーの直前に呼ばれる� SSH到達可能な場合はmysqld, mysqld_safeを強制killし、到達不可能な場合は電源OFF
すると良い
� master_ip_failover_script� マスターIPアドレスの更新や、アプリケーションから接続するためのユーザの作成など� フェイルオーバーの直前と、新マスター移行時(差分反映完了後)に呼ばれる
� 用途に合わせてスクリプトを書くことで、アプリケーション側の修正無しで新マスターに接続できる
� マスターのIPアドレスにVirtual IPを使っている場合– VIPを新マスターで割り当てる
� カタログデータベース等でマスターのIPアドレスを管理している場合– そのカタログデータベースを更新する
� report_script: フェイルオーバーの可否と詳細情報をメール通知したり� フェイルオーバーの終了後に呼ばれる
12
ケーススタディ
� DeNAのサービス(主にソーシャルゲーム)において、150を超えるマスター/スレーブのペアに対してMHAを導入
� MySQLは滅多にクラッシュしないが、OSやH/W障害によって落ちることはある
� 拡張ポイント� マスターのダウン検知
– Manager→マスターに加えて、2箇所のリモートのデータセンターからマスターに到達できないことをチェック
� マスターの強制ダウン– SSHで接続可能なときはkillall -9 mysqld mysqld_safe、接続できないときはipmitool等で強制電源OFF
� マスターのIPアドレスのフェイルオーバー– 集中管理しているデータベースがあり、そこを更新– マスター接続用のユーザ(INSERT/UPDATE/DELETE権限がある)を作成
� OSダウンによるフェイルオーバーには、ダウン検知に10秒、フェイルオーバーに4秒程度� マスターの生死判定
– 3秒×3-4 (9秒から12秒)
� フェイルオーバー可否判定– デフォルトの動作は、ほかのスレーブがすべて生きている場合のみフェイルオーバー– スレーブの稼働状況をチェックして判定 (1秒未満)
� フェイルオーバー処理– 現マスターの強制シャットダウン– SSHで接続可能なときは、差分バイナリログを保存– 新マスターの決定– 新マスターのIP有効化– ほかのスレーブが新マスターからレプリケーション再開
13
デモ
� 3台構成 (マスター1個、スレーブ2個)� Host centos6-1: Master
� Host centos6-2: Slave and Manager
� Host centos6-3: Slave
� マスターのmysqldをkill
� スレーブの片方を止めた状態でマスターを更新、そしてマスターのmysqldをkill (差分修復)
� スレーブの片方を止めた状態でマスターを更新、そしてマスターでカーネルパニック (差分修復)
14
既存のソリューションに対する優位性
� マスター障害が起きても、スレーブ間での整合性が崩れずに迅速にレプリケーションを再開できる� 障害検知に10秒程度→マスター修復に4秒程度
� 既存のMySQLレプリケーション構成を変える必要が無い� 従来型のシングルマスター/マルチスレーブ構成であればOK
� MySQL5.0以降であれば動作する(5.0/5.1/5.5/5.6で動作確認済み)
� 5.5の準同期レプリケーションと組み合わせることで、データ消失をほぼ防げる
� サーバの追加投資が不要� アクティブ/スタンバイ構成時のスタンバイ機のようなサーバが不要
� 管理サーバはスレーブ上で動作させることもできる� 独立した管理サーバを設け、多数のマスターを監視することもできる
� 既存のレプリケーション構成とほぼ同等のパフォーマンスを得られる� マスターに対して過度の負荷をかけたりはしない
� どのストレージエンジンでも動作する� MyISAM等、トランザクション非対応のストレージエンジンでも動作する
15
ほかの方法との比較
� Pacemaker + DRBDに対する優位性� 既存環境にそのまま入れることができる� スタンバイサーバが要らず、全サーバを有効活用できる� フェイルオーバー時間が高速(検知に10秒程度、切り替えに4秒程度)
– アクティブ/スタンバイ型のDRBDでは、クラッシュリカバリに1分単位は見ないといけない
� MySQL Cluster / Galeraに対する優位性� 既存環境にそのまま入れることができる� 難しくない (当社比)
� MySQL-MMMに対する優位性� MySQL-MMMはそもそもHAソリューションではない
– 稼働監視のNW経路が1本しかない
– マスター障害の状況によっては高確率で切り替えが止まる– 差分修復をしていない– 多数のVirtual IPが必須
– 切り替えが連続して起こる可能性があり、それを防ぐ手段が無い
16
その他の特徴
� 任意のスレーブを新マスターにできる (最新でなくても)
� フェイルバックをするのが面倒。障害マスターへの復旧には多くの場合作り直しが必要
– Fully durable settings (innodb_flush_log_at_trx_commit=1, innodb_support_xa=1 sync_binlog=1)でなければほかのHAソリューションでも同じ欠点がある
� 準同期レプリケーション(Semi-Synchronous Replication)を併用することで、データ消失をほぼ防げる� MySQL 5.5からオプションでサポートされた機能
� マスター障害時に「どのスレーブにも最新のコミット情報が転送されていない」という状況をほぼ防ぐことができる
� 全スレーブに同期されるわけではなく、「どれか1個のスレーブ」に対する同期を保証。このため、マスター障害時は各スレーブで状態がずれる可能性がある。MHAは最新のものをベースにほかのスレーブを復旧できる
17
サービスの増強と縮退
� ゲームタイトルの人気を正確に見積もることは困難� 想定外に人気が出ることもあるし、逆に人気が出ないこともある
� ある程度の期間が経過すれば、徐々に人気は下落傾向に入る
� 想定外の人気が出た場合� スレーブを追加する
� 水平分割によってマスターを追加していく
– サービスを止めずにマスターを追加することは可能
� マスターのハードウェアを増強する
– メモリ、SSD、ネットワーク
� 人気が下落傾向にある場合� スレーブを減らす
� マスターを低スペックなサーバに移す
� いくつかのマスターを1個のサーバに集約する
18
マスターを別マシンに移行したいとき
� マスターを別のマシンに移したいことはよくある� 増強:メモリの増設やHDD->SSDなどによって凌ぎたい
� 縮退:人気の低いゲームタイトルを低スペックなサーバに移したい
� 部分障害:ハードウェアの部分故障により性能が大幅に悪化したので移したい
– ダウンしていないものの、さばけるスループットが大幅に悪化
� H/W、Linux、MySQLのバージョンアップ:止めて上げなおすのは実質的に10分以上のダウンにつながるので厳しい
� メンテナンス時間を設ければ作業自体は簡単� マスターのIPアドレスを新しいものに更新し、スレーブは全部新しいマスタ
ーからレプリケーションする
� だがメンテナンスは何度もやりたくはない� ユーザへの告知、カスタマーサポートへの連絡などの事務手続き
� ダウンタイムは収益減になる
� 多くの場合深夜作業になるのでメンバーが疲弊する
19
ダウンタイム無しでマスター切り替え
� ダウンタイム無しでマスターを切り替えることが理想。そのためには…� マスターへの更新を一瞬止める� 既存のスレーブが、マスターからのレプリケーションをすべて終えたこと
を確認する� 新しいマスターへの書き込み権限を与え、
アプリケーションから透過的に(ロジックを書き換えずに)接続できるようにする
– 仮想IPを用いたり、マスターのIPをカタログデータベースで管理するのが定番
� スレーブが新しいマスターからレプリケーションを開始
� これらのステップを0.5-3秒くらいでできれば、多くの場合で許容範囲だろう� そのタイミングでの更新はエラーになるが、
ユーザから見ればもう1回クリックすれば成功するくらいの間隔なので
20
書き込みのブロックをどうするか
� MySQLでは更新をブロックする手段をいくつか提供しているが、すべてが安全なわけではない� FLUSH TABLES WITH READ LOCK
– クライアント側でタイムアウト設定をしていない限り、ずっとロック待ちになる:レスポンスタイムが悪くなる
– 実行中のトランザクションは実質エラーとなるほかのサーバにまたがって更新している場合に不整合を生む
– 全部のテーブルをフラッシュするので非常に時間がかかることがある事前にFLUSH NO_WRITE_TO_BINLOG TABLESしておくのが1つの定石
� SET GLOBAL read_only = 1
– 更新を実行した時点で即時にエラーが返る
– 実行中のトランザクションは実質エラーとなる
� アプリケーションから使っているユーザをDROPする
– 新規接続が張れなくなる
– 接続済みのセッションは、切断までエラーにならない
– ほかのサーバにまたがった更新でも不整合にはならない
– 接続済みのセッションが終了しない限り、更新が終わらない
– 持続的接続では効果が無い
21
安全性と高速性のバランスを取る
� マスターで長時間更新を実行しているセッションが無いことをチェック
– 100秒更新しているものは、スレーブでも100秒かかる
� ユーザをDROP
� 一定時間(最大3秒等)、アプリからの接続が無くなるまで待つ
– SHOW PROCESSLISTを見て、1秒以上Sleep状態なものは、単なる張りっぱな
しや外部で待っているとかなので、切っても構わないだろう
– 一番やってはいけないのは、コミット直前-途中のセッションを強制的に切ること
� 接続が無くなるか時間切れになったら、FLUSH TABLES WITH READ
LOCKにより全体をロックし、切り替えに入る
� 接続を張りっぱなしにしているデーモンプロセス等についての考慮も必要
� だいたい1秒もあればブロックが完了する
22
MHAでの高速マスター切り替え
� MHAではオプションでマス
ターをオンラインで切り替える機能がある� 手動で実行する
� マスターへの接続を0.5-2秒
程度ブロック
� その間に新マスターに切り替える
From:
host1 (current master)
+--host2 (backup)
+--host3 (slave)
+--host4 (slave)
+--host5 (remote)
To:
host2 (new master)
+--host3 (slave)
+--host4 (slave)
+--host5 (remote)
23
デモ
24
プロジェクトの詳細情報
� トップページ� http://code.google.com/p/mysql-master-ha/
� ドキュメント(英語)� http://code.google.com/p/mysql-master-ha/wiki/TableOfContents?tm=6
� 有志による日本語ドキュメント� http://myhome.munetika.mydns.jp/ossdbwiki/index.php/%E3%83%A1%E3%82%A4%E
3%83%B3%E3%83%9A%E3%83%BC%E3%82%B8
� ダウンロード(安定版)� http://code.google.com/p/mysql-master-ha/downloads/list
� GitHubリポジトリ(開発ツリー: 名称変更したので注意)� https://github.com/yoshinorim/mha4mysql-manager
� https://github.com/yoshinorim/mha4mysql-node
25
オープンソースを取り巻く世界
� ベンダー, SI, サードベンダー� 主にサポートやコンサルで収益を上げる
� 開発者を雇用
� サービス企業� オープンソース製品を利用することで、高い商用製品を買わずに済む
ベンダー(RedHat, MySQL, etc)
サービス企業(Facebook, Twitter, DeNA, etc)
SI/サードベンダー(HP, IBM, Percona, etc)
26
ベンダー(MySQL)からサービス事業者(DeNA)への転職
� MySQL時代の業務内容� 本業だったコンサルは、2-5日単位での案件を多数こなすという仕事
� 1ヶ月-6ヶ月といった、まとまった期間を取って
特定のソリューションに取り組むことは難しかった
� サービス事業者でないとできなかったこと� 中長期的な施策 (MHAは代表的な例)
� 1000台規模のサーバ運用の経験と、
そこから派生する潜在ニーズの発掘
– 「遅いトランザクションを特定するツール」の重要性や「監視のしきい値となるKPIをより正確に決める(いつサーバ追加が必要か等を適切に判断するために)」など
27
サービス企業の中からDeNAに行った理由
� 「スペシャリスト」というキャリアパスがある� マネージャにならなくても高い報酬を目指せるキャリアパス� 欧米企業では一般的だが、国内では珍しい
� データベーススペシャリストの働き場所は大規模サービス事業者でないと難しい� 5台のサーバを3台にするために
DBスペシャリストを雇用したいと思う経営者はいない� 1000台を600台にできるなら、
それだけで価値がある
� 為替レートの問題と、グローバル指向とのギャップを埋める� 今の時代、給与は日本円でもらいたい→日本企業� だがある程度海外での技術プレゼンスの意識があることが長期的には大事� 米MySQL Conferenceに参加している国内Webサービス企業は
mixi、Yahoo、楽天、DeNAくらいしか無い
� 付加価値の高い仕事をするためには、ある程度チームのメンバ層が厚いことが必要� チームマネジメント、トラブルシューティング、プロジェクト支援、勉強会の講師など� すべてが特定の人に降ってくるようでは、時間を確保することは困難
28
オープンソースに貢献する意義
� 「なぜノウハウを外に出す必要があるのか」ということをすべての会社が考えるようだと技術は発展しない
� 一種のCSR
� 技術の発展に貢献するというCSR
29
オープンソース・ソフトウェアの価値
� OSSに貢献すると言う ≠ OSS界に実際に貢献している� 言うだけなら誰でもできる� 「OSSとして出したいです」と言いながら何年も出ていないものはたくさんある
� OSSをリリースする ≠ 世の中に貢献する� リリースしたからといって役に立つとは限らない
� 現場で使っているソフトウェアを出す� 実験室で作っただけのソフトウェアと、現場で使われているソフトウェアは違う� MHAはMobageの150系統を超える環境で実際に使っていて、多数のメンテ
や障害時に活躍した実績がある
� 多くの人にとって使いやすいソフトウェアを出す� 公開したきり発展していない(ドキュメントも無い!)OSSは少なくない� MHAはMySQLサードベンダーのSkySQL(およびそのパートナー)が商用サ
ポートを提供している
30
インフラエンジニアのキャリア
最新の技術動向を(公開/非公開を問わず)
仕入れるためのアンテナ/人脈の構築
短中期的な問題を定義効果の高い手段をリストアップ・検証優先順位をつけて着実に実施
中長期的な課題の発見・解決策の立案/検証
国内外での積極的な情報発信Technology Marketing
Research & Development
Solution Development
地道な勉強によるスキルの底上げ
多くの検証環境での実験
Core Skill enhancement
経験を通じて定量的な理解を深める
Alliance
Problem Solving今そこにある火を消す
Tool development問題解決のために便利なツールを整備する
� DeNAはこうしたキャリアを積み上げる上で非常に向いています� もちろん、ソーシャルゲーム本体の開発者も絶賛募集中です
31
ありがとうございました