レプリケーションとは、多くのデータベース管理システムが採用している概念で、データベースのオリジナルとコピーのマスタースレーブ関係を定義します。マスタース側は更新を記録し、スレーブ群に通知されます。スレーブ側は更新を正しく受け取った問いうメッセージを送り、次の更新を受け付けられる状態であることを通知します。つまり、マスタースの役は更新情報を保持して、スレーブに更新情報を伝播することです。
レプリケーションを利用する最大のメリットはDB負荷(Disk IO, Memory, CPU使用率)を分散することです。参照系(Select)はスレーブで、更新系(INSERT, UPDATE, DELETE)はマスタースです。
そして、レプリケーションのデータモデリングには、マスタ系データとトランザクション系データという二つのデータの分類があります。マスタ系データは一度登録されたら頻繁には変更されないデータで、トランザクション系データは頻繁には変更・追加されるデータです。
レプリケーション遲延を考慮した設計や実装にする必要がある時にはSelectをマスタースに強制的に向ける必要があります。例えば、スレーブの参照処理の実行タイミングは、マスタースがスレーブに更新情報を伝播した後ではなく、伝播する前となると、参照した先のスレーブには更新した情報が反映されません。ここはこう考えばいいです。マスタ系データはスレーブに向けてたSelectクエリで取る、トランザクション系データはトランザクションの内容によってマスタース側に向けます。
しかし、このやり方は絶対正しいとは言えないです。例えば、更新と参照を同じマスタースのトランザクションにすると、下記の問題を発生することが可能です。
1. Lost Update Problem
トランザクションAが時間点t5にX值に更新して、時間点t6にトランザクションBにまた更新されて、トランザクションAのt5で更新する資料は失いました。
2. Uncommitted Dependency Problem
トランザクションBがトランザクションAの中に更新された資料を取ったが、この資料は時間点t6にトランザクションAでロールバックされた、その結果はトランザクションBで取った資料は間違った資料となりました。
3. Inconsistent Analysis Problem
時間点t1とt2にトランザクションAとBは同時にX值を取りました。両方も同じデータで更新にしますが、トランザクションBはトランザクションAの前にコミットしましたから、結果にトランザクションAは古いデータで更新続きました。
上記の状況を忘れないように、マスター・スレーブに向けてたSelectクエリを考えます。
あとは、データが遲延なしで同步することが見えるようにデータの更新をJsonにする方法があります。データがデプロイする時にメモリ上に展開するようにします。それはデータの参照度が一番高く見えるようになります。
レプリケーションについて、メリットやデメリットは下記のようにまとめることができます。
メリット:
- DB負荷(Disk IO, Memory, CPU使用率)を分散する、特に参照系のクエリ(Select)はスレーブに分担する
- サビースに大きく影響を与えず、バッグアップすることができる
- マスタースが障害発生時、スレーブに切り替えることができる
また上記という通り、レプリケーションには遲延というデメリットがあります。
デメリット:
- スレッドによって、レプリケーションにある程度な遲延を与える(マスタースレーブの間には完璧な同步が実現できないから)
- 遲延の間にマスタースが障害発生する場合、変更中の資料はリカバーできない
解決法:
- 必要なデータを探すときはインデックスで探す
- 無駄なロッグをしないように、インデックスの範囲を縮める
- リクエスト回数が多すぎないようにする
- リクエストのWhere条件も多すぎないようにする
- 切適なシャーディング策略が必要
それで、DBの設計に戻りました。インデックスが張っていれば、レコードが特定されてそこだけ行ロックできます。逆にインデックスがないと、行が特定できないのでテーブルロックが走して、サーバーのCPUを張り付く問題に発生します。それはサビースに大きな遲延を与えます。また、無駄インデックスが残っていると、意図がないインデックスが使われて、予想外のロックが取られるかもしれません。ここは、ExplainでSQLの実行計画を確認するべきです。実行のコストや回数などの発行が異常に高くなると、注意しなければなれません。
0 留言:
發佈留言