マママ n マ ママママ 1 ママママママママママママ 2011/08/09 do_aki
マスタ n 対 スレーブ 1
レプリケーションの作り方
2011/08/09 do_aki
自己紹介
• 識別: do_aki (どぅーあき)• 所属:(株)もしも• 生態:インフラ兼 Web アプリケーション
エンジニア
–サーバラッキング・ケーブリング–ネットワーク / ミドルウェア構築– WAF/ Library / Web アプリ / GUI アプ
リ( #isucon 参加します )
レプリケーション
一般的なレプリケーション
Master
Slave:1 Slave:2 Slave:n……
1:n
n:1 レプリケーション
MasterA
SlaveAB
MasterB
A と B 両方の データが格納
なぜ作ろうと思ったか
MasterA
Slave:1A
Slave:2A
Slave:3B
MasterB
アプリケーション
水平分割シャー
ディン
グ
Slave:4B
横断的な SQL が発行できない
MasterA
Slave:1A
Slave:2A
Slave:3B
MasterB
アプリケーション
Slave:4B
JOIN の壁
1:n1:n
n:1 レプリケーション
MasterA
SlaveAB
MasterB
JOIN 可能!
CHANGE MASTER TO
Master を切り替え
MasterA
SlaveAB
MasterB
Master を切り替え
MasterA
SlaveAB
MasterB
Master を切り替え
MasterA
SlaveAB
MasterB
START SLAVE 少し待つ
STOP SLAVE スレーブ止める
現在の位置を記録( Master_Log_File および Read_Master_Log_Pos )
CHANGE MASTER( 次のマスタへスイッチ )
Duplicate entry...
データ不整合 orz
レプリケーション(スレーブ)
Slave
data
IO SQL
relay log
Master から
エキスパートのための MySQL 運用 + 管理トラブルシューティングガイド より
レプリケーション(スレーブ)
Slave
data
IO SQL
relay log
Master から
エキスパートのための MySQL 運用 + 管理トラブルシューティングガイド より
CHANGE MASTER で消
される
binlog の 位置(SHOW SLAVE STATUS)
• IO thread: Master_Log_File Read_Master_Log_Pos
• SQL thread : Relay_Master_Log_File Exec_Master_Log_Pos
SQL thread の位置を利用すると
• 同じデータを再度取得–ネットワーク帯域–マスタへの負荷
• 切り替え時間が短いと進まない?
-> 却下
IO thread の位置まで待つ• MASTER_POS_WAIT(log_name,log_pos[,timeout])
この関数は、マスター / スレーブの同期化のコントロールに役立ちます。スレーブがマスターログで指定された位置まで読み取り、すべてのアップデートを適用するまでブロックします。戻り値は、指定の位置まで進むまでスレーブが待たなければいけないログ イベントの数です。この関数は、スレーブ SQL スレッドが開始されていない、スレーブのマスター情報が初期化されていない、引数が正しくない、またはエラーが発生、という場合は NULL を戻します。タイムアウトの時間を越えると -1 が戻されます。MASTER_POS_WAIT() の待機中にスレーブ SQL スレッドが停止すると、関数は NULL を戻します。スレーブが指定の位置を過ぎたら、関数はただちに戻しを行います。(以下略)
http://dev.mysql.com/doc/refman/5.1/ja/miscellaneous-functions.html#function_master-pos-wait
MASTER_POS_WAIT
指定したバイナリログの位置まで処理をブロック
Seconds_Behind_Master
が 0 になるまで待つ
START SLAVE
STOP SLAVE IO_THREAD
MASTER_POS_WAIT()
STOP SLAVE
CHANGE MASTER
IO thread が読み取った位置まで実行
Seconds_Behind_Master
が 0 になるまで待つ
START SLAVE
STOP SLAVE IO_THREAD
MASTER_POS_WAIT()
STOP SLAVE
CHANGE MASTER
原因不明の停止
STOP SLAVE IO_THREAD 時
IO thread :トランザクション途中でも停止する
SQL thread :トランザクション毎に実行してる
Seconds_Behind_Master
が 0 になるまで待つ
START SLAVE
STOP SLAVE IO_THREAD
MASTER_POS_WAIT()
Timeout?
START SLAVE IO_THREAD
STOP SLAVE
CHANGE MASTER
Yes
No
稼働実績
• 3 秒ごとの切り替え
• 1ヶ月近く安定稼働
• 目に見えるマスタの負荷はなし
まとめ
• n:1 レプリケーションは実現可能• 遅延は必ず発生してしまう– 集計に便利
• 実際にやってみると躓くことって結構ある
• ソースコードは github にあります( https://github.com/do-aki/SwitchMaster )
おしまい
かなり端折ったので伝わりにくかったら
ごめんなさい