Contenu connexe
Similaire à Principles of Transaction Processing Second Edition 9章 4~9節 (20)
Plus de Yuichiro Saito (16)
Principles of Transaction Processing Second Edition 9章 4~9節
- 3. 9.4 通常時の操作
レプリケーションのもっとも単純な形がタイトルに
ある⽅方式(Fig 9.7)。
マスターを持つ単⼀一のサーバを作り、そこから1つ以上の
セカンダリ(スレーブとも⾔言います)にデータを複写する。
データの更新は、マスタのみ可能。
セカンダリは、参照(ローカルクエリの処理)ができる。
⽅方法の⼀一つに、同期レプリケーションがある。
マスタに書き込みが⾏行行われた時、同時にセカンダリにコ
ピーを作成する。
プライマリとセカンダリデータのデータの⼀一貫性は保た
れるが、コピー作成の時間の分更新が遅れる。また、コ
ピーの制御を管理者が⾏行行えない。
(これだとパフォーマンスに難ありですよね、そこで…)
3
Yuichiro Saito
- 4. 9.4 通常時の操作
⾮非同期レプリケーションが今は⼀一般的。
プライマリに対する更新の処理と、セカンダリへのレプリケーションは
⾮非同期で実施。
レプリケーション時、ログを⽤用いる(後述に他の⽅方法)。そのため、処理の
順序は正確に反映される。
レプリケーションは、ホットバックアップの⼿手法である。データ
ベースミラーリングとも⾔言われる。
障害時の処理
プライマリで障害発⽣生時、セカンダリは障害発⽣生直前までの処理を⾏行行わ
なければならない。
同期であれば障害時のトランザクションは向こうになるが、問題は⾮非同
期。障害発⽣生時のログが届いていない可能性がある。
そこで、復帰時にセカンダリがプライマリが上がっているサーバのログ
を取りに⾏行行けるようにしておけば、⾮非同期の場合でも復帰しやすくなる。
(しかーし、MySQLではこの芸当はできません。)
See also: レプリケーションしてるMySQLで、マスタやスレーブが障害停
⽌止した場合のリカバリプラン
- (ひ)メモ
http://d.hatena.ne.jp/hirose31/20091023/1256259405
4
Yuichiro Saito
- 5. 9.4 通常時の操作
Fig 9.8を⾒見見ながら⽐比較しよう。
⾮非同期レプリケーションのもう⼀一つの⽅方法。
ログではなくクエリ(即ちSQL)を⽣生成してレプリケーションする。
MySQLはこの⽅方法。
⼿手法は汎⽤用的。ただし、セカンダリごとにクエリ処理が発⽣生する
ため時間がかかる。
更にもう⼀一つの処理。
ログを後処理する。ログ処理がオンメモリでオンライン処理され
る際、同時にレプリケーションしてしまう。
オーバーヘッドが低い。ただし、これ⽤用の実装をする必要がある。
ログのサイズが⼤大きくなることがあるため、ログのサイズを下げ
る後処理を通すことが推奨される。
中⽌止されたトランザクションを除外する。
最も⼩小さな単位にまとめなおす…レコードのフィールドなど。
さらに…トランザクションの更新をグループ化する。処理を直列化してセ
カンダリに更新を促せるので効率的。
5
Yuichiro Saito
- 6. 9.4 通常時の操作
システムによっては、テーブルごとに別の場所にレ
プリケートすることができる。
「バッファデータベース」が複雑なフィルタリング・ト
ランザクションの分割を提供している。
セカンダリごとに「バッファデータベース」のやり取り
を各々スケジューリングして転送する。
⼀一部システムのように、タイムスタンプなどを使ってレ
プリカが正確に適⽤用されたかの判断を助ける場合もある。
Two-phase commitとレプリケーション
6.8項「オプティミスティック同時実⾏行行制御」の応⽤用。
6
Yuichiro Saito
- 7. 9.4 通常時の操作
運⽤用
設定は柔軟にできる。ただ、レプリケーションを多岐にわたらせ
ると運⽤用が⾯面倒になる。
(商⽤用ソフトだと)運⽤用管理ツールがあるそうだ…
サポートしているミドルウェア
発祥はタンデムのNon-Stop SQL。その後VAXが続く。
IBM Infomix
http://publib.boulder.ibm.com/infocenter/idshelp/v111/
index.jsp?topic=/com.ibm.sqlt.doc/sqlt161.htm
MS SQL Server
http://msdn.microsoft.com/ja-jp/library/ms151198.aspx
MySQL
http://dev.mysql.com/doc/refman/5.1/ja/replication.html
Oracle
http://www.oracle.com/technetwork/database/features/data-
integration/index.html
Sybase
7
Yuichiro Saito
- 8. 9.4 通常時の操作
セカンダリの復旧
キャッチアップ時に注意する点は7章で学んだ「冪等」。
あまりにダウンタイムが⻑⾧長い時は、差分をとるより丸ごとコ
ピーした⽅方が結果として早い。
プライマリの復旧 (セカンダリが1台)
セカンダリが落ちる時より⾯面倒なのは間違いない。
プライマリの完全なコピーがあると思ったら⼤大間違い。複数台
あったら、全台で完全に同期しているかも疑わしい。でも、引
き継ぎたい。
そもそも、過負荷で落ちた事を誤感知しているかも。これを防
⽌止するため、watchdogを突っ込んで(Fig 9.9)の状況を把握で
きるようにしておく。
データを守るか、パフォーマンスを出すか。事前に同期・⾮非同
期レプリケーションを選んでおける事がほとんど。
8
Yuichiro Saito
- 9. 9.4 通常時の操作
プライマリの復旧 (セカンダリが複数台)
多数決とクォーラムコンセンサス
静的にプライマリとなるうる1つのレプリカを設定すればいいけど、そん
なに話は単純じゃない。
(Fig 9.10)のような構成の時、過半数が持っているデータが合致している
と確認できた場合、それが「正」となる。
マシン数は奇数がベスト。1:1の⽐比率になった時に結論が出ない。回避⽅方
法として、クォーラムコンセンサス
(Fig 9.11)のようにレプリカ単位で重
みをつけて問題を解決する。
リーチングコンセンサス
ポイント1: プライマリ切替の意思決定が同時に⾛走らないようにする。
ポイント2: 落ちた直後は不安定。落ち着くまで待たないとダメ。
そのため、事前に優先順位がついている。
流れを説明します…とうとうと。
ただ、うまく⾏行行かない時がある。その時は、番号は打ち直し。
また、R2がR1より⼤大きい番号を打ってしまって”軍拡競争”が始まる。ま
あ、これは解決できる。
9
Yuichiro Saito
- 10. 9.4 通常時の操作
最新状態確⽴立立
マスタが切り替わった際、以前のマスタが持っているデータと
永続性があれば、その先から積み上げてレプリケーションすれ
ばいい。
でも、うまく⾏行行かないかも。どっかでマージしないと。
各セカンダリが持っているデータを確認し、最新を持ち寄って
いるサーバのデータを配布してマージしよう。
⼀一貫性・可⽤用性・パーティションの追尾性 (CAP)
CAP経験則 – C,A,P のうち2つまでは満たせるが1つは満たせ
ない。トレードオフ。どれをとるの?(ここすごく重要な理屈)
同期レプリケーション: C, A
クォーラムコンセンサス: A, P
マルチマスタを使うと…また変わってくる。次節にて。
See also: CAPとBASE、ACIDの呪縛
http://www.slideshare.net/kimtea1983/capbaseacid
10
Yuichiro Saito
- 12. 9.5 便利な分離処理
障害によってデータベースが分断される事はあるけ
ど、それ以上に恣意的に分断するというオペレー
ションが便利な時があります。
例えば、ノートPCでデータを持ち出す、という事を
想定してください。
12
Yuichiro Saito
- 13. 9.5 マルチマスタでの更新の伝播⽅方法
複数のマスタがあるとき、どちらのデータをどうマージ
すればいいだろう?シングルマスタの時に主従関係とは
ここが決定的に違います。
(Fig 9.12) のように、変数
x を別のマシン上で⾮非同期で
更新すると、どちらが正しくなるかわからなくなります。
解決策
更新ではなく、レコード追加をしてしまう。それで済むならそ
れがいいね。
更新時に⼀一意のタイムスタンプタグをつける。
“Thomas’s write rule”がこれを解決。最新のものが正である。
“tombstone” – 削除されたデータの有効期限を設けて、削除
操作の寿命を設定する。
“Thomas’s write rule”では時計の時間同期は⼤大切。
13
Yuichiro Saito
- 14. 9.5 ノンブラインドアップデート
“Thomas’s write rule”は、ブラインドアップデート。
ユーザに依存しない、プログラムが勝⼿手にやること。
マルチマスタにすると、どうしても(Fig 9.14)の⽤用な
状況は避けられない。タイムスタンプを基準にする
と、x=1ではなくx=2が優先されてしまう。でも、
どっちが正しいかはまた違うハズ。
これを解決するには、「⼿手動」。えっ?と思われる
でしょうけど。
まあ、次の項で。
14
Yuichiro Saito
- 15. 9.5 バージョンベクトルによる衝突検知
⼿手動でマージするにしても、区別する何かが欲しい。
そこでバージョンベクトルを使う
更新時のxiとxkの競合について、流れを説明します。
6.6節で説明した「バージョン」の概念を⽤用いる。
「レプリカID(どのマスタか)」「更新回数」を組と
して、これをベクトルと⾒見見なす。
これを⽤用いてどう解決するかは2つの⼿手法がある。
次項にて。
See also: About Version Vectors (a.k.a. Vector
Clocks) - Java to the Limit
http://www.javalimit.com/2011/01/
understanding-vector-clocks.html
15
Yuichiro Saito
- 17. 9.7 データ共有システム
当然の事ながらロックされた時は他の誰かはアクセ
スできない。
Oracle RACなど、2つ以上のプロセスが1つのデー
タソースにアクセスする「共有」する仕組みがある。
この⽅方法をとる時に必要となるアルゴリズムや仕組みに
ついて学んで⾏行行きましょう。
ロック
物理的に隔離された各マシンのプロセスからロックを受
け付けるためのグローバルロックマネージャが必要。
グローバルロックマネージャは操作のオーバーヘッドが
でかい。ローカルロックと組み合わせてみる。
17
Yuichiro Saito
- 18. 9.7 データ共有システム
キャッシュ
2つのプロセスで、違いキャッシュを持ったりしないか?(Fig
9.17) NFSとかでも時折問題になりますね。
データマネージャが、ロックマネージャに更新された事を適切
に伝えるようにしておく必要がある。
データの領域毎に、パーティショニングしてそもそもこう⾔言っ
た問題が起こりづらくする事も良し。
ロギング
ログの仕組みは7章を読み返してください。
ログの書き出しはオーバーヘットになりやすい箇所。
各プロセスから直接ログを書き出せるようにする⽅方法がある。
ただ、通信量が増える。
プロセス毎にログを書き出す領域を確保して、そこに書かせる
⽅方法もある。通信量も減り、書き込み効率も⾼高い。
回復時は、最後に書いたログを適切に⾒見見つけ出せるようにして
おかなければならない。
18
Yuichiro Saito