web-dev-qa-db-ja.com

マルチマスターOracle GoldenGateレプリケーションのグローバルロック

これは非常に複雑なシナリオですが、dba.seの多くのハイエンドユーザーの一部が最新の課題に興味を持つかもしれないと考えました。

問題

私は、Oracle GoldenGateを利用して、wikiにいくらか似たドキュメント制作システム向けの大陸間データレプリケーションソリューションに取り組んでいます。主な目標は、世界中でアプリケーションのパフォーマンスと可用性を向上させることです。

このソリューションでは、複数の場所からの同じデータプールへの同時読み取り/書き込みアクセスを許可する必要があります。つまり、ユーザーの介入なしに競合する更新を防止または解決するための巧妙な方法が必要です。

衝突防止に焦点を当てて、オブジェクト(ドキュメント、イラスト、メタデータのセットなど)をグローバルにロックできるようにする必要があります。これにより、複数のユーザーが異なる場所から同じオブジェクトを同時に編集できなくなり、最終的に競合が発生します。

同様に、ユーザーの接続データベースがそのオブジェクトの更新されたデータを受信するまで、オブジェクトはロックされたままである必要があります。ユーザーが最新の更新なしに古いオブジェクトの編集を開始する可能性は低くなります。

背景

このアプリケーションは遅延に敏感であり、中央のデータセンターへのアクセスが遠隔地から遅くなります。多くのコンテンツ重視のシステムと同様に、読み取り/書き込み比率は4対1のラインにあり、分散アーキテクチャの候補として適しています。適切に管理されている場合、後者はサイトまたはネットワークの停止中の可用性を確保するためにも機能します。

やや慣例にとらわれないマルチループ双方向レプリケーショントポロジを使用しました。これにより、複雑さが管理可能なレベル{2(n-1)way}に保たれ、サイトの停止に対する回復力が追加され、サイトの追加または削除がかなり簡単になります。わずかな欠点は、中央のマスターデータベースを介してほとんどのリモートサイト間でトランザクションが複製されるまでに最大30秒かかる場合があることです。

すべてのサイト間で直接複製を行う従来の設計では、その時間が半分に短縮されますが、構成の複雑さが大幅に増加します{n(n-1)way}。

私の設計では8方向のレプリケーションではなく、20方向のレプリケーションを意味する5つの場所があります。

この図は、ヨーロッパ、アジア、北米のデータセンター全体の現在のテスト環境を示しています。本番環境には、追加の場所が必要です。

Illustration of replication topology

すべてのデータベースは、Oracle GoldenGate 11.2.1を備えたOracle 11.2.0.3です。

これまでの私の考え

中央データベースへのデータベースリンクを介して「ロック」テーブルに行を挿入し、ロック解除(前述の行の更新または削除)を更新とともに複製できるようにすることで、ロックを実行する方法について考えてきました。データ。

ユーザーに代わって、ロックを取得してオブジェクトを編集用に開く前に、中央データベースとローカルデータベースの両方でロックの可用性を確認する必要があります。編集が完了したら、ローカルデータベースのロックを解放する必要があります。これにより、変更が複製され、中央データベースを介して他のすべての場所にロックが解放されます。

ただし、待ち時間の長いデータベースリンクでのクエリは非常に遅くなる可能性があり(テストでは、1回の挿入で1.5秒から7秒の範囲が表示されます)、ロックを削除する更新または削除ステートメントが保証できるかどうかはわかりません複製される最後のステートメントです。

リモートPL/SQLプロシージャを呼び出してチェックとロックを行うと、少なくとも1つのリモートクエリに操作が制限されますが、7秒は非常に長い時間です。 2秒のようなものがより受け入れられます。どういうわけか、データベースリンクを最適化できることを願っています。

ローカルロックテーブルの行が中央データベースから正常に複製される前に、その行を削除または更新しようとするなどの追加の問題が発生する場合もあります。

明るい面では、この種のソリューションでは、中央データベースへの通信が中断された場合にアプリケーションを読み取り専用状態にしたり、リダイレクトしたりするのが比較的簡単である必要がありますデータセンターが利用できなくなった場合のクライアント。

似たようなことをした人はいますか?これに取り組む最善の方法は何ですか?

最初に言ったように、これはかなり複雑な解決策です。不明な点や省略された点について気軽に質問してください。

6
Roy

私が行うほとんどの作業はPostgreSQLでの作業であるため、これは100%のお金になる場合もあればそうでない場合もありますが、これは参考になるほど十分に近いはずです。

基本的な問題は、このような環境では、ロックの管理に多大な問題が発生することです。ロックレベルで何らかの競合解決または競合防止を実行できるようです。競合の防止は、パフォーマンスの問題にもかかわらず、ユーザーのフラストレーションのレベルを大幅に削減するようです。

ここでの私のアプローチは、実際にpl/sqlストアドプロシージャで中央サーバーをロックし、可能な場合はロックテーブルに挿入して、成功を示す値を返すか、それが不可能な場合は、失敗したり、例外を発生させたりします(たとえば、私が過去に行ったことは、既にロックされている場合、誰がロックを持っているかを識別する何かを返すことです)。

省略したいのは、実際にローカルサーバーをチェックすることです。読み取りと書き込みの比率が高く、それ以外の場合は衝突の可能性が比較的小さい場合は、とにかく中央サーバーを確認する必要がほとんどあるため、ローカルサーバーを確認してもあまりメリットはありません。確かに、ロックのためにローカルサーバーとリモートサーバーの両方に書き込みたくないでしょう。ロックをシンプルに保ちます。それはあなたが何をしようとも痛みの原因になりそうです。

私がここで提案する2番目のことは、私はhighlyこのようなロックを、おそらく2時間後に期限切れにすることを推奨することです。これを行う主な理由は2つあります。 1つ目は、コードのアプリケーションレイヤーのバグが原因でロックが解除されないことです。2つ目は、これがWebインターフェイスを介している場合、HTTPはステートレスであるため、状態が低下したことを実際に知る方法がありません。このようにして、特定の期間有効なロックを与えることができ、事前に(必要に応じてバックグラウンドで)更新でき、個人がブラウザウィンドウを閉じてその日に帰宅するとタイムアウトします。ロックを解放するためのある種の管理ユーティリティも私がお勧めするものです。

ロックを取得するのに7秒かかるとパフォーマンスが大幅に低下しますが、結局、これを行うにはこれ以上の方法はないと思います。オプションはCAPの定理によって大幅に制限され、単一の中央ロックシステムがおそらく必要です。

別のオプションとして、中央サーバーにブランチロケーションを単にロックさせ、有効なロックが一定期間保持されなくなったらすぐにブランチロケーションにロックを解放させることもできます。これには、チームによるより迅速なコラボレーションを可能にするという利点があります。つまり、チームの最初の編集者だけがそのコストを負担する必要があります。

1
Chris Travers