Upload
yoshihiko-matsuzaki
View
29.718
Download
0
Embed Size (px)
DESCRIPTION
<SKILL BASECAMP 2013> MySQLの冗長化~無停止運用を実現するには~ http://www.pasonatech.co.jp/entry/index.jsp?mode=2&d=on&no=3756
Citation preview
MySQLの冗長化 ~無停止運用を実現するには~
株式会社ハートビーツ 運用エンジニア 松崎 慶彦
自己紹介
• 松崎 慶彦 (MATSUZAKI Yoshihiko)
• 株式会社ハートビーツ 運用エンジニア
▫ MSP(サーバ運用・監視)の会社
▫ 24時間有人監視を提供している
▫ ベンダ非依存なサーバ運用(どこでもやる)
• 普段やっている業務
▫ サービス特性に合ったインフラの設計・構築
▫ サービス特性に合った運用の設計
▫ すでに動いているサービスの移設
2013.1.24 © MATSUZAKI Yoshihiko
MySQL
• 世界シェアトップのオープンソースRDBMS
• 導入が楽
• 枯れているので運用も楽
• 十分に高速
• 開発が活発でどんどん新機能が増えている
2013.1.24 © MATSUZAKI Yoshihiko
MySQLの最新情報
2013.1.24 © MATSUZAKI Yoshihiko
http://dev.mysql.com/
MySQLを使う上で大事なこと
• ちゃんとしたスキーマ設計
• ちゃんとしたクエリ設計
2013.1.24 © MATSUZAKI Yoshihiko
▫ パフォーマンスはほとんどここで決まる
MySQL冗長化についての要望
• 動作を速くしてほしい!
• 負荷を下げてほしい!
• 無停止にしてほしい!
• データをロストさせたくない!
• 無停止でバックアップを取りたい!
• いざというときにスケールさせたい!
2013.1.24 © MATSUZAKI Yoshihiko
• でもアプリはなるべく変更したくない…… ▫ スキーマやクエリはなかなか変えられない
MySQLの冗長化手段
• MySQL Cluster
• DRBD
• MySQL Replication
2013.1.24 © MATSUZAKI Yoshihiko
MySQL Cluster
• 監視・起動・停止・復旧まで自動でやってくれる
• クラスタウェアが不要でmysqldだけで動作する
• マスターの負荷分散ができる
• トランザクション分離レベルやインデックスの制限がある
▫ スキーマ設計・クエリ設計での配慮が必要になる
2013.1.24 © MATSUZAKI Yoshihiko
トランザクション分離レベル
• 待ち時間と一貫性のトレードオフ
▫ 分離レベルが高いほど一貫性が強く待ち時間が長くなる
• 分離レベルが低いと起きる現象
▫ Dirty Read
並列実行されている別トランザクションによる
未コミットの更新を読み込んでしまう
▫ Non-Repeatable Read
並列実行されている別トランザクションによる
コミット済みのレコード変更を読み込んでしまう
▫ Phantom Read
並列実行されている別トランザクションによる
コミット済みのレコード追加・削除を読み込んでしまう
2013.1.24 © MATSUZAKI Yoshihiko
トランザクション分離レベル
• SERIALIZABLE
▫ 他トランザクションのコミットの影響を受けない
• REPEATABLE READ
▫ 参照中レコードのみ他トランザクションの影響を受けない
▫ Phantom Read
• READ COMMITTED
▫ 他トランザクションのコミット済みデータを読み込む
▫ Non-Repeatable Read, Phantom Read
• READ UNCOMMITTED
▫ 他トランザクションの未コミットデータを読み込む
▫ Dirty Read, Non-Repeatable Read, Phantom Read
2013.1.24 © MATSUZAKI Yoshihiko
←MySQL Clusterで使用できるのはこれのみ
DRBD
• ネットワーク越しにブロックデバイスをミラーリング
▫ ネットワークのレイテンシの影響を受けやすい
• コア機能がカーネルモジュール
▫ クラウドでは採用しにくい
• Failoverの仕組みを別に用意する必要がある
2013.1.24 © MATSUZAKI Yoshihiko
MySQL Replication
• マスターで実行したSQLをスレーブでも実行することで
データを複製する
• 最も導入が簡単
• スキーマやクエリの制限もほとんどない
• Failoverの仕組みを別に用意する必要がある
2013.1.24 © MATSUZAKI Yoshihiko
Replication
2013.1.24 © MATSUZAKI Yoshihiko
レプリケーションの仕組み
2013.1.24 © MATSUZAKI Yoshihiko
レプリケーションの仕組み
2013.1.24 © MATSUZAKI Yoshihiko
レプリケーションの仕組み
2013.1.24 © MATSUZAKI Yoshihiko
レプリケーションの仕組み
2013.1.24 © MATSUZAKI Yoshihiko
レプリケーションの仕組み
2013.1.24 © MATSUZAKI Yoshihiko
ログポジション
• スレーブがバイナリログを読み込み始める位置
▫ CHANGE MASTER文で指定する
2013.1.24 © MATSUZAKI Yoshihiko
ログポジションを誤ると…
• データが抜け落ちてしまう
▫ 抜け落ちたデータへのUPDATEやDELETEで壊れる
2013.1.24 © MATSUZAKI Yoshihiko
ログポジションを誤ると…
• データが二重で更新されてしまう
▫ UNIQUEなキーを含んでいると失敗して壊れる
2013.1.24 © MATSUZAKI Yoshihiko
レプリケーションの注意点
• スレーブに書き込むと壊れる
▫ スレーブのread_onlyを有効にする
• ログポジションに十分気を付ける
▫ 不整合が起きるまでエラーがないので気付けない
マスターが更新されていない状態で取得する
▫ なるべく自分で入力しない
mysqldump --master-data
▫ GTID (after MySQL 5.6)
2013.1.24 © MATSUZAKI Yoshihiko
• 壊れたら再構築するしかないので慎重に…
準同期レプリケーション
• 準同期 (Semi-Synchronous)
▫ I/Oスレッドは同期
▫ SQLスレッドは非同期
• after MySQL 5.5
• スレーブへのバイナリログ転送が保証される
2013.1.24 © MATSUZAKI Yoshihiko
準同期レプリケーションの仕組み
2013.1.24 © MATSUZAKI Yoshihiko
準同期レプリケーションの仕組み
2013.1.24 © MATSUZAKI Yoshihiko
準同期レプリケーションの仕組み
2013.1.24 © MATSUZAKI Yoshihiko
準同期レプリケーションの仕組み
2013.1.24 © MATSUZAKI Yoshihiko
準同期レプリケーションの仕組み
2013.1.24 © MATSUZAKI Yoshihiko
準同期レプリケーションの注意点
• 複数台のスレーブがある場合
1台がAckを返した時点でCOMMIT完了になる
▫ 用途に応じて構成を決める
• マスターはAckを待っている間COMMITが止まる
▫ スレーブ障害がマスターに伝播する可能性がある
▫ rpl_semi_sync_master_timeoutを短くする
Webサーバのタイムアウト時間
ブラウザのタイムアウト時間
2013.1.24 © MATSUZAKI Yoshihiko
Failover
2013.1.24 © MATSUZAKI Yoshihiko
簡単なFailover構成の一例
2013.1.24 © MATSUZAKI Yoshihiko
簡単なFailover構成の一例
2013.1.24 © MATSUZAKI Yoshihiko
簡単なFailover構成の一例
2013.1.24 © MATSUZAKI Yoshihiko
簡単なFailover構成の一例
2013.1.24 © MATSUZAKI Yoshihiko
簡単なFailover構成の一例
2013.1.24 © MATSUZAKI Yoshihiko
Failoverの基本的な流れ
• マスターの障害を検知
• マスターを仮想IPから除外
• マスターとのレプリケーションを停止
• (新マスターに昇格するスレーブを決定)
• (新マスターのログポジションを保存)
• 新マスターに仮想IPを切り替え
• (残りのスレーブを新マスターに接続)
2013.1.24 © MATSUZAKI Yoshihiko
• MySQLとは別に実装する必要がある
MySQLまわりのFailover
• マスターの障害を検知
• マスターを仮想IPから除外
• マスターとのレプリケーションを停止
• (新マスターに昇格するスレーブを決定)
• (新マスターのログポジションを保存)
• 新マスターに仮想IPを切り替え
• (残りのスレーブを新マスターに接続)
2013.1.24 © MATSUZAKI Yoshihiko
MySQLまわりのFailover
• MySQL MHA
▫ マスターがダウンしたら最新のスレーブをマスターにする
▫ ManagerとNode(各DB)の構成でやや構築コストが高い
• mysqlfailover (after MySQL 5.6)
▫ マスターがダウンしたら最新のスレーブをマスターにする
▫ Pythonで書かれたMySQL公式のFailoverスクリプト
• 自前
▫ 最新のスレーブ判別は準同期レプリケーションで代用可能
▫ そんなに複雑な処理でもないのでわりと簡単に書ける
2013.1.24 © MATSUZAKI Yoshihiko
仮想IPアドレスまわりのFailover
• マスターの障害を検知
• マスターを仮想IPから除外
• マスターとのレプリケーションを停止
• (新マスターに昇格するスレーブを決定)
• (新マスターのログポジションを保存)
• 新マスターに仮想IPを切り替え
• (残りのスレーブを新マスターに接続)
2013.1.24 © MATSUZAKI Yoshihiko
仮想IPアドレスまわりのFailover
• LVS (keepalived)
▫ keepalived自身の冗長化が簡単にできる
▫ ヘルスチェックがTCPぐらいしかないので作り込みが必要
▫ スケールする構成にしやすい
• Pacemaker
▫ スケールする構成にできない
• HAProxy
▫ HAProxy自身の冗長化が自力でできない
• MySQL Proxy
▫ MySQL Proxy自身の冗長化が自力でできない
▫ 正式版リリースではない
2013.1.24 © MATSUZAKI Yoshihiko
Failoverの注意点
• 最新のデータがどこにあるかを把握する
▫ 準同期レプリケーション (after MySQL 5.5)
▫ 更新系クエリの経路を常に1つに維持する
• 復旧前の誤ったサービス復帰を防止する
▫ reset slave
▫ skip-slave-start
▫ chkconfig mysqld off
• 書き込み可能な状態にする
▫ スレーブを昇格させるときにread_onlyを外す
2013.1.24 © MATSUZAKI Yoshihiko
LVS (keepalived)
2013.1.24 © MATSUZAKI Yoshihiko
LVS (keepalived)
• 仮想IPへのアクセスを別のサーバに振り分ける
• 自分自身のFailoverができる
• 自前のスクリプトでヘルスチェックができる
▫ 要求定義に応じた柔軟なヘルスチェック
▫ 障害発生時にFailoverを発動したりもできる
• 一つの仮想IPへのアクセスを複数のサーバに振
り分けられる
▫ 単純なラウンドロビンだけでなく接続数を見て
ロードバランシングしたりもできる
2013.1.24 © MATSUZAKI Yoshihiko
LVS (keepalived)の設定例
virtual_server 192.168.0.1 3306 {
delay_loop 6
lb_algo wrr
lb_kind DR
protocol TCP
sorry_server 192.168.0.102 3306
real_server 192.168.0.101 3306 {
weight 1
MISC_CHECK {
misc_path "/path/to/mysql-check.sh 192.168.0.101"
misc_timeout 60
}
}
}
2013.1.24 © MATSUZAKI Yoshihiko
↑
自前のスクリプトでヘルスチェック
Failover時以外はスレーブに
アクセスが行かないように
↓sorry_serverで設定する
スケールアウト
2013.1.24 © MATSUZAKI Yoshihiko
簡単なスケールする構成の一例
(スケールする構成への変更前)
2013.1.24 © MATSUZAKI Yoshihiko
簡単なスケールする構成の一例
(スケールする構成への変更後)
2013.1.24 © MATSUZAKI Yoshihiko
簡単なスケールする構成の一例
(更新系Failover)
2013.1.24 © MATSUZAKI Yoshihiko
簡単なスケールする構成の一例
(更新系Failover)
2013.1.24 © MATSUZAKI Yoshihiko
簡単なスケールする構成の一例
(更新系Failover)
2013.1.24 © MATSUZAKI Yoshihiko
簡単なスケールする構成の一例
(更新系Failover)
2013.1.24 © MATSUZAKI Yoshihiko
簡単なスケールする構成の一例 (中段スレーブ障害での参照系Failover)
2013.1.24 © MATSUZAKI Yoshihiko
簡単なスケールする構成の一例 (中段スレーブ障害での参照系Failover)
2013.1.24 © MATSUZAKI Yoshihiko
簡単なスケールする構成の一例 (中段スレーブ障害での参照系Failover)
2013.1.24 © MATSUZAKI Yoshihiko
簡単なスケールする構成の一例 (スレーブ障害での切り離し・Failover)
2013.1.24 © MATSUZAKI Yoshihiko
簡単なスケールする構成の一例 (スレーブ障害での切り離し・Failover)
2013.1.24 © MATSUZAKI Yoshihiko
簡単なスケールする構成の一例 (スレーブ障害での切り離し・Failover)
2013.1.24 © MATSUZAKI Yoshihiko
簡単なスケールする構成の一例 (スレーブ障害での切り離し・Failover)
2013.1.24 © MATSUZAKI Yoshihiko
簡単なスケールする構成の一例 (スレーブ障害での切り離し・Failover)
2013.1.24 © MATSUZAKI Yoshihiko
スケールアウトの注意点
• 現用系に影響を与えないようにする
• server_idがユニークであることを担保する
▫ 同じserver_idのスレーブがぶら下がると壊れる
▫ LAN内でユニークな値を使用する
▫ オートスケールなら自動で書き換える
▫ 手動なら書き換える前に接続しないようにする
skip-slave-start
chkconfig mysqld off
• Replicationで実行される更新系の負荷は分散できない
▫ SQLスレッドはシングルスレッドなのでスケールアップでも無理
マスターの分割
2013.1.24 © MATSUZAKI Yoshihiko
スケールアウトの注意点
• 無停止で稼働中のスレーブを増やす
▫ mysqldump --single-transaction --master-data
MyISAMでやるとテーブルロックで障害になる
▫ 仮想化基盤の機能でクローン
データの一貫性を保証する必要がある
• 理想はクローン用のスタンバイ機
▫ サービスに組み込まない
▫ 一貫性のあるクローンが影響なく素早く取れる
2013.1.24 © MATSUZAKI Yoshihiko
▫ 予算と相談……
実運用
2013.1.24 © MATSUZAKI Yoshihiko
実運用で大切なこと
• データサイズ
▫ 大きくなるとスケールが難しくなる
ダンプ時間
リストア時間
クローン時間
▫ 目安は大きくても20GB程度
マスター分割
不要データの定期削除
▫ バイナリログのサイズ
▫ InnoDBログのサイズ
2013.1.24 © MATSUZAKI Yoshihiko
実運用で大切なこと
• とにかく事前にテストをする
▫ すべてのDBサーバのダウンについて検証する
▫ 実際のスキーマ・実際の負荷で検証する
• 何を重視するか探って設計の着地点を見つける
▫ 無停止性
▫ データロストの回避
▫ 運用コスト
▫ 予算
▫ スケジュール
2013.1.24 © MATSUZAKI Yoshihiko
まとめ
• 完全な無停止(停止時間ゼロ)はできない
▫ どんな構成でもだいたい十数秒はかかる
▫ できるだけ迅速に復旧できる体制作り
サーバだけでなく人も
• さまざまな条件の中で落とし所を見つける
▫ 条件は技術的なことだけではない
2013.1.24 © MATSUZAKI Yoshihiko
ご清聴ありがとうございました。
2013.1.24 © MATSUZAKI Yoshihiko